1 Commits

Author SHA1 Message Date
Alexei Sorokin
bdd55f611f [CORE] Another fix for the inboxnoticestream query 2020-06-11 21:52:44 +01:00
12289 changed files with 112298 additions and 1276135 deletions

View File

@@ -12,16 +12,6 @@ Load and Storage:
- New media handling system - New media handling system
- GS is now structurely divided in includes and public - GS is now structurely divided in includes and public
- OEmbed upgraded to Embed plugin (Now we provide Open Graph information too) - OEmbed upgraded to Embed plugin (Now we provide Open Graph information too)
- Added Redis based caching and queues
- Improved memcached support
Federation:
- Added ActivityPub support
- RemoteFollow: Remote follow ActivityPub and OStatus remote actors via the click of a button
- ActorLists: Allow to create collections of Actors and to interact with them - supports both OStatus and ActivityPub
- The Free Network: Automagically migrate internal remote profiles between Free Network protocols
- Enabled the search box to import remote notices and profiles
- Improvements on Nodeinfo (and new route)
General: General:
- Composer was integrated - Composer was integrated
@@ -29,16 +19,56 @@ General:
Modules: Modules:
- Restored built-in plugins - Restored built-in plugins
- New modules system: core plugins and plugins physically separated - New modules system: core plugins and plugins physically separated
- Refactor of Plugin API to better illustrate the idea of modules
- Bug fixes of core modules logic - Bug fixes of core modules logic
- Improved plugin management tool (now all available plugins are shown and third party can be uploaded and deleted)
#### TODO before alpha:
Load and Storage:
- Upgrade STOMP queue
- Add Redis based caching and queues
- Review memcached based cache
- Port PEAR DB to PDO_DataObject
- Support PostgreSQL
Network:
- Port PEAR HTTP to Guzzle
- Port PEAR Mail to PHPSendMail
- Add OAuth2 support (deprecate OAuth1)
- Add shinny new Plugins management interface for sysadmins together with a new doc for devs
Federation:
- Add ActivityPub support
- Fix audience targeting
- Add Group Actor Type
- OstatusSub: Remote follow OS and AP profiles via OStatusSub
- ActorLists: Allow to create collections of Actors and to interact with them - supports both OS and AP
- The Free Network: Automagically migrate internal remote profiles between Free Network protocols (check Nodeinfo)
- Enable the search box to import remote notices and profiles
General:
- Fix failling unit tests
- Improve Cronish
- Run session garbage collection
- Cleanup Email Registration
- Refactoring of confirmation codes
- Refactoring of Exceptions
Modules:
- Document conversion of older plugins to the new GS 2
- Create installer for v2 plugins
- Introduce new metadata for plugins (category and thumb)
- Improve plugin management tool (add install form and better UI that makes use of new metadata)
- Add plugin management tool as a install step
- Allow to install remote plugins and suggest popular trusted ones
## v1.20.9release - The Invicta Crusade ## v1.20.9release - The Invicta Crusade
Dropped Support for PHP5.6.x. Minimum PHP version now is 7.0.0. Release name chosen after Porto city. Porto is one of the oldest cities in Europe and thanks to its fierce resistance
during two battles and sieges in history, it has earned the epithet of Cidade Invicta (Invincible City). The dev team
behind this release studies in Porto, Portugal.
Release name chosen after Porto city. Porto is one of the oldest cities in Europe and thanks to its fierce resistance during Dropped Support for PHP5.6.x. Minimum PHP version now is 7.0.0.
two battles and sieges in history, it has earned the epithet of Cidade Invicta (Invincible City). The dev team behind this
release studies in Porto, Portugal.
Major changes from previous release: Major changes from previous release:

View File

@@ -46,7 +46,7 @@ Additional Contributors
* Blaine Cook * Blaine Cook
* Henry Story * Henry Story
* Melvin Carvalho * Melvin Carvalho
* Stéphane Bérubé * chimo
* Akio * Akio
* Maiyannah Bishop * Maiyannah Bishop
* Bob Mottram * Bob Mottram
@@ -55,6 +55,7 @@ Additional Contributors
* Moonman * Moonman
* Normandy * Normandy
* Verius * Verius
* Alexei Sorokin
* Daniel Supernault * Daniel Supernault
Credits for StatusNet Credits for StatusNet

View File

@@ -1,7 +1,7 @@
GNU social Coding Style GNU social Coding Style
=========================== ===========================
Please comply with [PSR-12](https://www.php-fig.org/psr/psr-12/) and the following standard when working on GNU social Please comply with [PSR-2](https://www.php-fig.org/psr/psr-2/) and the following standard when working on GNU social
if you want your patches accepted and modules included in supported releases. if you want your patches accepted and modules included in supported releases.
If you see code which doesn't comply with the below, please fix it :) If you see code which doesn't comply with the below, please fix it :)
@@ -118,7 +118,7 @@ Some short hands are evil:
Naming conventions Naming conventions
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Respect PSR-12 first. Respect PSR2 first.
- Classes use PascalCase (e.g. MyClass). - Classes use PascalCase (e.g. MyClass).
- Functions/Methods use camelCase (e.g. myFunction). - Functions/Methods use camelCase (e.g. myFunction).
@@ -145,29 +145,11 @@ Also, whereever possible, avoid ambiguous terms. For example, don't use text
as a term for a variable. Call back to "contents" above. as a term for a variable. Call back to "contents" above.
Arrays
-------------------------------------------------------------------------------
Even though PSR-12 doesn't specifically specify rules for array formatting, it
is in the spirit of it to have every array element on a new line like is done
for function and class method arguments and condition expressions, if there is
more than one element.
In this case, even the last element should end on a comma, to ease later
element addition.
$foo = ['first' => 'unu'];
$bar = [
'first' => 'once',
'second' => 'twice',
'third' => 'thrice',
];
Comparisons Comparisons
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Always use symbol based comparison operators (&&, ||) instead of text based Always use symbol based comparison operators (&&, ||) instead of text based
operators (and, or) in an "if" clause as they are evaluated in different order operators (AND, OR) as they are evaluated in different orders and at different
and at different speeds. speeds. This is will prevent any confusion or strange results.
This is will prevent any confusion or strange results.
Use English Use English

View File

@@ -229,6 +229,12 @@ StartPersonalGroupNav: beginning of personal group nav menu
EndPersonalGroupNav: end of personal group nav menu (good place to add a menu item) EndPersonalGroupNav: end of personal group nav menu (good place to add a menu item)
- $action: action object being shown - $action: action object being shown
StartGroupGroupNav: Showing the group nav menu
- $action: the current action
EndGroupGroupNav: At the end of the group nav menu
- $action: the current action
StartEndHTML: just before the </html> tag StartEndHTML: just before the </html> tag
- $action: action object being shown - $action: action object being shown
@@ -349,12 +355,6 @@ EndAvatarSaveForm: after saving the avatar
StartNewQueueManager: before trying to start a new queue manager; good for plugins implementing new queue manager classes StartNewQueueManager: before trying to start a new queue manager; good for plugins implementing new queue manager classes
- $qm: empty queue manager to set - $qm: empty queue manager to set
StartInitializeQueueManager: about to register queue handlers in the queue manager; good for plugins to register own handlers
- $qm: queue manager
EndInitializeQueueManager: after registering queue handlers in the queue manager; good for plugins to register own handlers
- $qm: queue manager
RedirectToLogin: event when we force a redirect to login (like when going to a settings page on a remembered login) RedirectToLogin: event when we force a redirect to login (like when going to a settings page on a remembered login)
- $action: action object being shown - $action: action object being shown
- $user: current user - $user: current user
@@ -1496,16 +1496,3 @@ StartDocNav: Before outputting the docs Nav
EndDocNav: After outputting the docs Nav EndDocNav: After outputting the docs Nav
- $nav: The DoclNav widget - $nav: The DoclNav widget
StartNoticeSearch: Before finding notices that match the given query
- string $query: The text query
StartNoticeSearchShowResults: Before displaying notices matching the query
- $out: HTMLOutputter used to output
- $query: The text query
- $notices: Array of DB notice objects
EndNoticeSearchShowResults: After displaying notices matching the query
- $out: HTMLOutputter used to output
- $query: The text query
- $notices: Array of DB notice objects

View File

@@ -1,8 +1,8 @@
Plugin Development Plugin Development
================== =======================
SamplePlugin.php SamplePlugin.php
---------------- -----------------------
Each plugin requires a main class to interact with the GNU social system. Each plugin requires a main class to interact with the GNU social system.
@@ -15,7 +15,7 @@ have pre-defined arguments, based on which event they're handling. A typical
event handler: event handler:
```php ```php
public function onSomeEvent($paramA, &$paramB): bool function onSomeEvent($paramA, &$paramB)
{ {
if ($paramA == 'jed') { if ($paramA == 'jed') {
throw new Exception(sprintf(_m("Invalid parameter %s"), $paramA)); throw new Exception(sprintf(_m("Invalid parameter %s"), $paramA));
@@ -26,7 +26,7 @@ public function onSomeEvent($paramA, &$paramB): bool
``` ```
Event Handlers Event Handlers
-------------- -----------------------
Event handlers must return a Boolean value. Event handlers must return a Boolean value.
@@ -41,43 +41,50 @@ If the handler throws an exception, processing will stop, and the exception's
error will be shown to the user. error will be shown to the user.
Installation Installation
------------ ------------------
To enable a plugin (like the SamplePlugin), site admins add the following code to their To install a plugin (like this one), site admins add the following code to their
config.php file: config.php file:
```php ```php
addPlugin('Sample'); addPlugin('Sample');
``` ```
Third Party Plugins must be installed in `local/plugins/{$name}/{$pluginclass}.php` Plugins must be installed in one of the following directories:
* local/plugins/{$pluginclass}.php
* local/plugins/{$name}/{$pluginclass}.php
* local/{$pluginclass}.php
* local/{$name}/{$pluginclass}.php
* plugins/{$pluginclass}.php
* plugins/{$name}/{$pluginclass}.php
Here, `{$name}` is the name of the plugin, like 'Sample', and `{$pluginclass}` Here, `{$name}` is the name of the plugin, like 'Sample', and `{$pluginclass}`
is the name of the main class, like 'SamplePlugin'. Plugins that are part of is the name of the main class, like 'SamplePlugin'. Plugins that are part of
the main GNU social distribution go in 'plugins' and third-party or local ones the main GNU social distribution go in 'plugins' and third-party or local ones
go in 'local'. go in 'local'.
Simple plugins can be implemented as a single plugin. Others are more complex Simple plugins can be implemented as a single module. Others are more complex
and require additional plugins; these should use their own directory, like and require additional modules; these should use their own directory, like
'local/plugins/{$name}/'. All files related to the plugin, including images, 'local/plugins/{$name}/'. All files related to the plugin, including images,
JavaScript, CSS, external libraries or PHP plugins should go in the plugin JavaScript, CSS, external libraries or PHP modules should go in the plugin
directory. directory.
Plugin Configuration Plugin Configuration
-------------------- ------------------
Plugins are configured using public instance attributes. To set their values, Plugins are configured using public instance attributes. To set their values,
site administrators use this syntax: site administrators use this syntax:
```php ```php
addPlugin('Sample', ['attr1' => 'foo', 'attr2' => 'bar']); addPlugin('Sample', ('attr1' => 'foo', 'attr2' => 'bar'));
``` ```
The same plugin class can be initialized multiple times with different arguments: The same plugin class can be initialized multiple times with different arguments:
```php ```php
addPlugin('EmailNotify', ['sendTo' => 'evan@status.net']); addPlugin('EmailNotify', array('sendTo' => 'evan@status.net'));
addPlugin('EmailNotify', ['sendTo' => 'brionv@status.net']); addPlugin('EmailNotify', array('sendTo' => 'brionv@status.net'));
``` ```
```php ```php
@@ -89,34 +96,34 @@ class SamplePlugin extends Plugin
``` ```
Initialization Initialization
-------------- ------------------
Plugins overload this method to do any initialization they need, like connecting Plugins overload this method to do any initialization they need, like connecting
to remote servers or creating paths or so on. @return bool hook value; true to remote servers or creating paths or so on. @return boolean hook value; true
means continue processing, false means stop. means continue processing, false means stop.
```php ```php
public function initialize(): bool function initialize()
{ {
return true; return true;
} }
``` ```
Clean Up Clean Up
-------- ------------------
Plugins overload this method to do any cleanup they need, like disconnecting from Plugins overload this method to do any cleanup they need, like disconnecting from
remote servers or deleting temp files or so on. remote servers or deleting temp files or so on.
```php ```php
public function cleanup(): bool function cleanup()
{ {
return true; return true;
} }
``` ```
Database schema setup Database schema setup
--------------------- ------------------
Plugins can add their own tables to the GNU social database. Plugins should use Plugins can add their own tables to the GNU social database. Plugins should use
GNU social's schema interface to add or delete tables. The ensureTable() method GNU social's schema interface to add or delete tables. The ensureTable() method
@@ -128,26 +135,25 @@ the checkschema.php script is run, greatly improving performance. However, they
need to remember to run that script after installing or upgrading a plugin! need to remember to run that script after installing or upgrading a plugin!
```php ```php
public function onCheckSchema(): bool function onCheckSchema()
{ {
$schema = Schema::get(); $schema = Schema::get();
// '''For storing user-submitted flags on profiles''' // '''For storing user-submitted flags on profiles'''
$schema->ensureTable('user_greeting_count',[ $schema->ensureTable('user_greeting_count',
new ColumnDef('user_id', 'integer', null, true, 'PRI'), array(new ColumnDef('user_id', 'integer', null,
new ColumnDef('greeting_count', 'integer') true, 'PRI'),
] new ColumnDef('greeting_count', 'integer')));
);
return true; return true;
} }
``` ```
Load related plugins when needed Load related modules when needed
-------------------------------- ------------------
Most non-trivial plugins will require extra plugins to do their work. Typically Most non-trivial plugins will require extra modules to do their work. Typically
these include data classes, action classes, widget classes, or external libraries. these include data classes, action classes, widget classes, or external libraries.
This method receives a class name and loads the PHP file related to that class. This method receives a class name and loads the PHP file related to that class.
@@ -160,9 +166,9 @@ in this plugin! So, make sure to return true by default to let other plugins,
and the core code, get a chance. and the core code, get a chance.
```php ```php
public function onAutoload($cls): bool function onAutoload($cls)
{ {
$dir = __DIR__; $dir = dirname(__FILE__);
switch ($cls) switch ($cls)
{ {
@@ -179,7 +185,7 @@ public function onAutoload($cls): bool
``` ```
Map URLs to actions Map URLs to actions
------------------- ------------------
This event handler lets the plugin map URLs on the site to actions (and thus an This event handler lets the plugin map URLs on the site to actions (and thus an
action handler class). Note that the action handler class for an action will be action handler class). Note that the action handler class for an action will be
@@ -187,28 +193,28 @@ named 'FoobarAction', where action = 'foobar'. The class must be loaded in the
onAutoload() method. onAutoload() method.
```php ```php
public function onRouterInitialized($m): bool function onRouterInitialized($m)
{ {
$m->connect('main/hello', $m->connect('main/hello',
['action' => 'hello']); array('action' => 'hello'));
return true; return true;
} }
``` ```
Modify the default menu to link to our custom action Modify the default menu to link to our custom action
----------------------------------------------------- ------------------
Using event handlers, it's possible to modify the default UI for pages almost Using event handlers, it's possible to modify the default UI for pages almost
without limit. In this method, we add a menu item to the default primary menu without limit. In this method, we add a menu item to the default primary menu
for the interface to link to our action. for the interface to link to our action.
Action Class Action Class
------------ ------------------
The Action class provides a rich set of events to hook, as well as output methods. The Action class provides a rich set of events to hook, as well as output methods.
```php ```php
public function onEndPrimaryNav($action): bool function onEndPrimaryNav($action)
{ {
// '''common_local_url()''' gets the correct URL for the action name we provide // '''common_local_url()''' gets the correct URL for the action name we provide
@@ -217,22 +223,20 @@ public function onEndPrimaryNav($action): bool
return true; return true;
} }
public function onPluginVersion(&$versions): bool function onPluginVersion(&$versions)
{ {
$versions[] = [ $versions[] = array('name' => 'Sample',
'name' => 'Sample', 'version' => STATUSNET_VERSION,
'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber, Evan Prodromou', 'author' => 'Brion Vibber, Evan Prodromou',
'homepage' => 'http://example.org/plugin', 'homepage' => 'http://example.org/plugin',
'rawdescription' => 'rawdescription' =>
_m('A sample plugin to show basics of development for new hackers.') _m('A sample plugin to show basics of development for new hackers.'));
];
return true; return true;
} }
``` ```
hello.php hello.php
--------- ------------------
This section is taken directly from the 'hello.php'. ( plugins/Sample/hello.php ) This section is taken directly from the 'hello.php'. ( plugins/Sample/hello.php )
@@ -251,7 +255,7 @@ class HelloAction extends Action
``` ```
Take arguments for running Take arguments for running
-------------------------- ------------------
This method is called first, and it lets the action class get all its arguments This method is called first, and it lets the action class get all its arguments
and validate them. It's also the time to fetch any relevant data from the database. and validate them. It's also the time to fetch any relevant data from the database.
@@ -260,7 +264,7 @@ Action classes should run parent::prepare(array $args = []) as the first line
of this method to make sure the default argument-processing happens. of this method to make sure the default argument-processing happens.
```php ```php
public function prepare(array $args = []): bool function prepare(array $args = [])
{ {
parent::prepare($args); parent::prepare($args);
@@ -275,14 +279,14 @@ public function prepare(array $args = []): bool
``` ```
Handle request Handle request
-------------- ------------------
This is the main method for handling a request. Note that most preparation This is the main method for handling a request. Note that most preparation
should be done in the prepare() method; by the time handle() is called the should be done in the prepare() method; by the time handle() is called the
action should be more or less ready to go. action should be more or less ready to go.
```php ```php
public function handle(): void function handle()
{ {
parent::handle(); parent::handle();
@@ -296,7 +300,7 @@ Title of this page
Override this method to show a custom title. Override this method to show a custom title.
```php ```php
public function title(): string function title()
{ {
if (empty($this->user)) { if (empty($this->user)) {
return _m('Hello'); return _m('Hello');
@@ -307,7 +311,7 @@ public function title(): string
``` ```
Show content in the content area Show content in the content area
-------------------------------- ------------------
The default GNU social page has a lot of decorations: menus, logos, tabs, all The default GNU social page has a lot of decorations: menus, logos, tabs, all
that jazz. This method is used to show content in the content area of the that jazz. This method is used to show content in the content area of the
@@ -315,15 +319,15 @@ page; it's the main thing you want to overload. This method also demonstrates
use of a plural localized string. use of a plural localized string.
```php ```php
public function showContent(): void function showContent()
{ {
if (empty($this->user)) { if (empty($this->user)) {
$this->element('p', ['class' => 'greeting'], $this->element('p', array('class' => 'greeting'),
_m('Hello, stranger!')); _m('Hello, stranger!'));
} else { } else {
$this->element('p', ['class' => 'greeting'], $this->element('p', array('class' => 'greeting'),
sprintf(_m('Hello, %s'), $this->user->nickname)); sprintf(_m('Hello, %s'), $this->user->nickname));
$this->element('p', ['class' => 'greeting_count'], $this->element('p', array('class' => 'greeting_count'),
sprintf(_m('I have greeted you %d time.', sprintf(_m('I have greeted you %d time.',
'I have greeted you %d times.', 'I have greeted you %d times.',
$this->gc->greeting_count), $this->gc->greeting_count),
@@ -333,7 +337,7 @@ public function showContent(): void
``` ```
Return true if read only. Return true if read only.
------------------------- ------------------
Some actions only read from the database; others read and write. The simple Some actions only read from the database; others read and write. The simple
database load-balancer built into GNU social will direct read-only actions to database load-balancer built into GNU social will direct read-only actions to
@@ -343,8 +347,9 @@ This defaults to false to avoid data integrity issues, but you should make sure
to overload it for performance gains. to overload it for performance gains.
```php ```php
public function isReadOnly($args): bool function isReadOnly($args)
{ {
return false; return false;
} }
``` ```

View File

@@ -1,90 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/**
* Fun sample plugin: tweaks input data and adds a 'Cornify' widget to sidebar.
*
* @category Plugin
* @package GNUsocial
* @author Jeroen De Dauw <jeroendedauw@gmail.com>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class AwesomenessPlugin extends Plugin
{
const PLUGIN_VERSION = '13.37.42';
public function onPluginVersion(array &$versions): bool
{
$versions[] = [
'name' => 'Awesomeness',
'version' => self::PLUGIN_VERSION,
'author' => 'Jeroen De Dauw',
'homepage' => GNUSOCIAL_ENGINE_REPO_URL . 'tree/master/plugins/Awesomeness',
// TRANS: Plugin description for a sample plugin.
'rawdescription' => _m('The Awesomeness plugin adds additional awesomeness ' .
'to a GNU social installation.')
];
return true;
}
/**
* Add the conrnify button
*
* @param Action $action the current action
*
* @return void
*/
public function onEndShowSections(Action $action)
{
$action->elementStart('div', ['id' => 'cornify_section',
'class' => 'section']);
$action->raw(
<<<EOT
<a href="https://www.cornify.com" onclick="cornify_add();return false;">
<img src="https://www.cornify.com/assets/cornify.gif" width="61" height="16" border="0" alt="Cornify" />
</a>
EOT
);
$action->elementEnd('div');
}
public function onEndShowScripts(Action $action)
{
$action->script($this->path('js/cornify.js'));
}
/**
* Hook for new-notice form processing to take our HTML goodies;
* won't affect API posting etc.
*
* @param NewNoticeAction $action
* @param User $user
* @param string $content
* @param array $options
* @return bool hook return
*/
public function onStartSaveNewNoticeWeb($action, $user, &$content, &$options)
{
$content = htmlspecialchars($content);
$options['rendered'] = preg_replace("/(^|\s|-)((?:awesome|awesomeness)[\?!\.\,]?)(\s|$)/i", " <b>$2</b> ", $content);
}
}

View File

@@ -1,25 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-14 14:51+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. TRANS: Module description for a sample plugin.
#: AwesomenessModule.php:67
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Afrikaans (http://www.transifex.com/gnu-social/gnu-social/language/af/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: af\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic (http://www.transifex.com/gnu-social/gnu-social/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic (Egypt) (http://www.transifex.com/gnu-social/gnu-social/language/ar_EG/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar_EG\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Asturian (http://www.transifex.com/gnu-social/gnu-social/language/ast/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ast\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Belarusian (Tarask) (http://www.transifex.com/gnu-social/gnu-social/language/be@tarask/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: be@tarask\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Дапаўненьне Awesomeness дадае незвычайныя магчымасьці ў усталяваньне GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://www.transifex.com/gnu-social/gnu-social/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bengali (India) (http://www.transifex.com/gnu-social/gnu-social/language/bn_IN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bn_IN\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Breton (http://www.transifex.com/gnu-social/gnu-social/language/br/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: br\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Catalan (http://www.transifex.com/gnu-social/gnu-social/language/ca/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Czech (http://www.transifex.com/gnu-social/gnu-social/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Danish (http://www.transifex.com/gnu-social/gnu-social/language/da/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: da\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2019-08-21 14:01+0100\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: German (http://www.transifex.com/gnu-social/gnu-social/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Das Awesomeness-Plugin fügt zusätzliche Großartigkeit zu einer GNU social-Installation hinzu."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Greek (http://www.transifex.com/gnu-social/gnu-social/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: el\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,26 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
# Luke Hollins <luke@farcry.ca>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-03-07 12:44+0000\n"
"Last-Translator: Luke Hollins <luke@farcry.ca>\n"
"Language-Team: English (United Kingdom) (http://www.transifex.com/gnu-social/gnu-social/language/en_GB/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "The Awesomeness plugin adds additional awesomeness to a GNU social installation."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://www.transifex.com/gnu-social/gnu-social/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,26 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
# Juan Riquelme González <soulchainer@gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-26 08:53+0000\n"
"Last-Translator: Juan Riquelme González <soulchainer@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/gnu-social/gnu-social/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "El complemento Awesomeness ('Molonosidad') incrementa en +20 la molonosidad de un sitio GNU social. (Este es un complemento de ejemplo, con un toque de humor)."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2012 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Basque (http://www.transifex.com/gnu-social/gnu-social/language/eu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Awesomeness pluginak informazio osagarria gehitzen dio GNU social instalatzioari."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Persian (http://www.transifex.com/gnu-social/gnu-social/language/fa/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fa\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Finnish (http://www.transifex.com/gnu-social/gnu-social/language/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fi\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Awesomeness-liitännäinen lisää ylimääräistä upeutta (awesomeness) GNU social-asennukseesi."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: French (http://www.transifex.com/gnu-social/gnu-social/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Le plugin Awesomeness ajoute des suppléments impressionnants à une installation de GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Friulian (http://www.transifex.com/gnu-social/gnu-social/language/fur/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fur\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Galician (http://www.transifex.com/gnu-social/gnu-social/language/gl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "O complemento impresionante engade suplementos impresionantes á instalación do GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Hebrew (http://www.transifex.com/gnu-social/gnu-social/language/he/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: he\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "תוסף מגניבות מוסיף עוד מגניבות להתקנה של סטטוסנט."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Upper Sorbian (http://www.transifex.com/gnu-social/gnu-social/language/hsb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: hsb\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hungarian (http://www.transifex.com/gnu-social/gnu-social/language/hu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: hu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Armenian (Armenia) (http://www.transifex.com/gnu-social/gnu-social/language/hy_AM/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: hy_AM\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Interlingua (http://www.transifex.com/gnu-social/gnu-social/language/ia/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ia\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Le plug-in Awesomeness rende un installation de GNU social plus impressionante."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Indonesian (http://www.transifex.com/gnu-social/gnu-social/language/id/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,26 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
# Ciencisto Dementa <maliktunga@users.noreply.github.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-06-15 01:03+0000\n"
"Last-Translator: Ciencisto Dementa <maliktunga@users.noreply.github.com>\n"
"Language-Team: Ido (http://www.transifex.com/gnu-social/gnu-social/language/io/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: io\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "L'extensilo Awesomeness adjuntas impresanta suplemento a GNU social-instaluro."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://www.transifex.com/gnu-social/gnu-social/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2012 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Italian (http://www.transifex.com/gnu-social/gnu-social/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Il plugin Awesomeness aggiunge ulteriore imponenza all'installazione di GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Japanese (http://www.transifex.com/gnu-social/gnu-social/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Georgian (http://www.transifex.com/gnu-social/gnu-social/language/ka/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ka\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Korean (http://www.transifex.com/gnu-social/gnu-social/language/ko/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Colognian (http://www.transifex.com/gnu-social/gnu-social/language/ksh/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ksh\n"
"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Luxembourgish (http://www.transifex.com/gnu-social/gnu-social/language/lb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lb\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Lithuanian (http://www.transifex.com/gnu-social/gnu-social/language/lt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lt\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:39+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Latvian (http://www.transifex.com/gnu-social/gnu-social/language/lv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lv\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 16:19+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Malagasy (http://www.transifex.com/gnu-social/gnu-social/language/mg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: mg\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Macedonian (http://www.transifex.com/gnu-social/gnu-social/language/mk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: mk\n"
"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Приклучокот „Феноменалност“ ѝ дава дополнителна феноменалност на инсталацијата на GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Malayalam (http://www.transifex.com/gnu-social/gnu-social/language/ml/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ml\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Malay (http://www.transifex.com/gnu-social/gnu-social/language/ms/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ms\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Burmese (http://www.transifex.com/gnu-social/gnu-social/language/my/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: my\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmål (http://www.transifex.com/gnu-social/gnu-social/language/nb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nb\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:30+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Nepali (http://www.transifex.com/gnu-social/gnu-social/language/ne/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ne\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Dutch (http://www.transifex.com/gnu-social/gnu-social/language/nl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "De Awesomenessplug-in voegt extra awesomeness toe aan een GNU socialinstallatie."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Nynorsk (http://www.transifex.com/gnu-social/gnu-social/language/nn/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nn\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2012 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Polish (http://www.transifex.com/gnu-social/gnu-social/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Wtyczka Awesomeness dodaje dodatkowe niesamowitości do instalacji GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Portuguese (http://www.transifex.com/gnu-social/gnu-social/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "O plugin de Espectacularidade adiciona espectacularidade adicional a uma instalação de GNU social."

View File

@@ -1,26 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
# Matheus Henrique Silva <hennsilvam@gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-25 08:09+0000\n"
"Last-Translator: Matheus Henrique Silva <hennsilvam@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/gnu-social/gnu-social/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "O plugin Awesomeness adiciona incríveis bonus à instalação de GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Romanian (Romania) (http://www.transifex.com/gnu-social/gnu-social/language/ro_RO/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ro_RO\n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Russian (http://www.transifex.com/gnu-social/gnu-social/language/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Потрясающий плагин добавляет потрясающие вещи в GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Slovenian (http://www.transifex.com/gnu-social/gnu-social/language/sl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Serbian (http://www.transifex.com/gnu-social/gnu-social/language/sr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sr\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,26 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
# Kristoffer Grundström <kristoffer.grundstrom1983@gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-09-15 18:38+0000\n"
"Last-Translator: Kristoffer Grundström <kristoffer.grundstrom1983@gmail.com>\n"
"Language-Team: Swedish (http://www.transifex.com/gnu-social/gnu-social/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Insticksprogrammet Awesomeness lägger till ytterligare ypperlighet till en GNU social-installation."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 08:48+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Tamil (http://www.transifex.com/gnu-social/gnu-social/language/ta/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ta\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Telugu (http://www.transifex.com/gnu-social/gnu-social/language/te/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: te\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Tagalog (http://www.transifex.com/gnu-social/gnu-social/language/tl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: tl\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Ang pampasak ng Pagiging Kahanga-hanga ay nagdaragdag ng karagdagang pagiging kahanga-hanga sa isang pagtatalaga ng GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Turkish (http://www.transifex.com/gnu-social/gnu-social/language/tr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: tr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 15:02+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Ukrainian (http://www.transifex.com/gnu-social/gnu-social/language/uk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: uk\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr "Напрочуд дивовижний додаток додає додаткову напрочуд дивовижну функціональність до вашої інсталяції GNU social."

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Urdu (Pakistan) (http://www.transifex.com/gnu-social/gnu-social/language/ur_PK/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ur_PK\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Vietnamese (http://www.transifex.com/gnu-social/gnu-social/language/vi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: vi\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese (http://www.transifex.com/gnu-social/gnu-social/language/zh/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/gnu-social/gnu-social/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,25 +0,0 @@
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-06 14:56+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/gnu-social/gnu-social/language/zh_TW/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_TW\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. TRANS: Plugin description for a sample plugin.
#: AwesomenessPlugin.php:55
msgid ""
"The Awesomeness plugin adds additional awesomeness to a GNU social "
"installation."
msgstr ""

View File

@@ -1,241 +0,0 @@
/*
_______ ,-----. .-------. ,---. .--..-./`) ________ ____ __
/ __ \ .' .-, '. | _ _ \ | \ | |\ .-.')| | \ \ / /
| ,_/ \__) / ,-.| \ _ \ | ( ' ) | | , \ | |/ `-' \| .----' \ _. / '
,-./ ) ; \ '_ / | :|(_ o _) / | |\_ \| | `-'`"`| _|____ _( )_ .'
\ '_ '`) | _`,/ \ _/ || (_,_).' __ | _( )_\ | .---. |_( )_ | ___(_ o _)'
> (_) ) __: ( '\_/ \ ;| |\ \ | || (_ o _) | | | (_ o._)__|| |(_,_)'
( . .-'_/ )\ `"/ \ ) / | | \ `' /| (_,_)\ | | | |(_,_) | `-' /
`-'`-' / '. \_/``".' | | \ / | | | | | | | | \ /
`._____.' '-----' ''-' `'-' '--' '--' '---' '---' `-..-'
*/
var cornify_count = 0;
var cornify_add = function(options) {
// Track how often we cornified.
cornify_count += 1;
var cornify_url = 'https://www.cornify.com/';
// Create a container DIV for our 'corn or 'bow.
var div = document.createElement('div');
div.style.position = 'fixed';
// Prepare our lovely variables.
var numType = 'px';
var heightRandom = Math.random() * 0.75;
var windowHeight = 768;
var windowWidth = 1024;
var height = 0;
var width = 0;
var de = document.documentElement;
// Get the window width and height - requires some cross browser checking.
if(typeof(window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
windowWidth = window.innerWidth;
} else if(de && de.clientHeight) {
windowHeight = de.clientHeight;
windowWidth = de.clientWidth;
} else {
numType = '%';
height = Math.round(height*100) + '%';
}
div.onclick = cornify_add; // Click for more magic.
div.style.zIndex = 10;
div.style.outline = 0;
if(cornify_count == 15) {
// Clicking 15 times summons the grand unicorn - which is centered on the screen.
div.style.top = Math.max( 0, Math.round((windowHeight-530)/2)) + 'px';
div.style.left = Math.round((windowWidth-530)/2) + 'px';
div.style.zIndex = 1000;
} else {
// Otherwise we randomize the position.
if(numType == 'px') {
div.style.top = Math.round( windowHeight*heightRandom ) + numType;
} else {
div.style.top = height;
}
div.style.left = Math.round(Math.random()*90) + '%';
}
var img = document.createElement('img');
var currentTime = new Date();
// Used as a cache buster so the browser makes a new request every time instead of usign the previous, cached one.
var submitTime = currentTime.getTime();
if( cornify_count==15 ) submitTime = 0;
// Construct our unicorn & rainbow request.
var url = cornify_url+'getacorn.php?r='+submitTime+'&url='+document.location.href;
// Add younicorns if requested.
if(options && (options.y || options.younicorns)) {
url += '&y='+(options.y ? options.y : options.younicorns);
if(Math.random() > 0.5) {
// Flip horizontally at random.
div.style.transform = 'scaleX(-1)';
};
}
img.setAttribute('src', url);
// Add a nice hover transition.
var ease = "all .1s linear";
div.style.WebkitTransition = ease;
div.style.WebkitTransform = "rotate(1deg) scale(1.01,1.01)";
div.style.transition = "all .1s linear";
div.onmouseover = function() {
var size = 1 + Math.round(Math.random()*10)/100;
var angle = Math.round(Math.random()*20-10);
var result = "rotate("+angle+"deg) scale("+size+","+size+")";
this.style.transform = result;
this.style.WebkitTransform = result;
};
div.onmouseout = function() {
var size = .9+Math.round(Math.random()*10)/100;
var angle = Math.round(Math.random()*6-3);
var result = "rotate("+angle+"deg) scale("+size+","+size+")";
this.style.transform = result;
this.style.WebkitTransform = result;
};
// Append our container DIV to the page.
var body = document.getElementsByTagName('body')[0];
body.appendChild(div);
div.appendChild(img);
// Hooray - now we have a sparkly unicorn (or rainbow) on the page. Another cornification well done. Congrats!
// When clicking 5 times, add a custom stylesheet to make the page look awesome.
if(cornify_count == 5) {
var cssExisting = document.getElementById('__cornify_css');
if(!cssExisting) {
var head = document.getElementsByTagName("head")[0];
var css = document.createElement('link');
css.id = '__cornify_css';
css.type = 'text/css';
css.rel = 'stylesheet';
css.href = 'https://www.cornify.com/css/cornify.css';
css.media = 'screen';
head.appendChild(css);
}
cornify_replace();
}
cornify_updatecount();
};
// Tracks how often we cornified.
var cornify_updatecount = function() {
var p = document.getElementById('cornifycount');
if(p == null) {
var p = document.createElement('p');
p.id = 'cornifycount';
p.style.position = 'fixed';
p.style.bottom = '5px';
p.style.left = '0px';
p.style.right = '0px';
p.style.zIndex = '1000000000';
p.style.color = '#ff00ff';
p.style.textAlign = 'center';
p.style.fontSize = '24px';
p.style.fontFamily = "'Comic Sans MS', 'Comic Sans', 'Marker Felt', serif"; // Only the best!
var body = document.getElementsByTagName('body')[0];
body.appendChild(p);
}
if(cornify_count == 1) {
p.innerHTML = cornify_count+' UNICORN OR RAINBOW CREATED';
} else {
p.innerHTML = cornify_count+' UNICORNS &AMP; RAINBOWS CREATED';
}
// Stores our count in a cookie for our next session.
cornify_setcookie('cornify', cornify_count+'', 1000);
};
var cornify_setcookie = function(name, value, days) {
var d = new Date();
d.setTime(d.getTime()+(days*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = name + "=" + value + "; " + expires;
};
var cornify_getcookie = function(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if(c.indexOf(name)==0) {
return c.substring(name.length,c.length);
}
}
return "";
};
// Retrieve our click count from the cookie when we start up.
cornify_count = parseInt(cornify_getcookie('cornify'));
if(isNaN(cornify_count)) {
cornify_count = 0;
}
// Adds happy words at the beginning of all headers on the page.
var cornify_replace = function() {
// Replace text.
var hc = 6;
var hs;
var h;
var k;
var words = ['Happy','Sparkly','Glittery','Fun','Magical','Lovely','Cute','Charming','Amazing','Wonderful'];
while(hc >= 1) {
hs = document.getElementsByTagName('h' + hc);
for (k = 0; k < hs.length; k++) {
h = hs[k];
h.innerHTML = words[Math.floor(Math.random()*words.length)] + ' ' + h.innerHTML;
}
hc-=1;
}
};
/*
* Adapted from http://www.snaptortoise.com/konami-js/
*/
var cornami = {
input:"",
pattern:"38384040373937396665",
clear:setTimeout('cornami.clear_input()', 5000),
load: function() {
window.document.onkeydown = function(e) {
if (cornami.input == cornami.pattern) {
cornify_add();
clearTimeout(cornami.clear);
return;
}
else {
cornami.input += e ? e.keyCode : event.keyCode;
if (cornami.input == cornami.pattern) cornify_add();
clearTimeout(cornami.clear);
cornami.clear = setTimeout("cornami.clear_input()", 5000);
}
};
},
clear_input: function() {
cornami.input="";
clearTimeout(cornami.clear);
}
};
cornami.load();

View File

@@ -1,246 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* A sample plugin to show best practices for GNU social plugins
*
* @package GNU social
* @author Brion Vibber <brionv@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
defined('GNUSOCIAL') || die();
/**
* Sample plugin main class
*
* Each plugin requires a main class to interact with the StatusNet system.
*
* The main class usually extends the Plugin class that comes with StatusNet.
*
* The class has standard-named methods that will be called when certain events
* happen in the code base. These methods have names like 'onX' where X is an
* event name (see EVENTS.txt for the list of available events). Event handlers
* have pre-defined arguments, based on which event they're handling. A typical
* event handler:
*
* function onSomeEvent($paramA, &$paramB)
* {
* if ($paramA == 'jed') {
* throw new Exception(sprintf(_m("Invalid parameter %s"), $paramA));
* }
* $paramB = 'spock';
* return true;
* }
*
* Event handlers must return a boolean value. If they return false, all other
* event handlers for this event (in other plugins) will be skipped, and in some
* cases the default processing for that event would be skipped. This is great for
* replacing the default action of an event.
*
* If the handler returns true, processing of other event handlers and the default
* processing will continue. This is great for extending existing functionality.
*
* If the handler throws an exception, processing will stop, and the exception's
* error will be shown to the user.
*
* To install a plugin (like this one), site admins add the following code to
* their config.php file:
*
* addPlugin('Sample');
*
* Plugins must be installed in one of the following directories:
*
* local/plugins/{$pluginclass}.php
* local/plugins/{$name}/{$pluginclass}.php
* local/{$pluginclass}.php
* local/{$name}/{$pluginclass}.php
* plugins/{$pluginclass}.php
* plugins/{$name}/{$pluginclass}.php
*
* Here, {$name} is the name of the plugin, like 'Sample', and {$pluginclass} is
* the name of the main class, like 'SamplePlugin'. Plugins that are part of the
* main StatusNet distribution go in 'plugins' and third-party or local ones go
* in 'local'.
*
* Simple plugins can be implemented as a single plugin. Others are more complex
* and require additional plugins; these should use their own directory, like
* 'local/plugins/{$name}/'. All files related to the plugin, including images,
* JavaScript, CSS, external libraries or PHP plugins should go in the plugin
* directory.
*
* @category Sample
* @package GNU social
* @author Brion Vibber <brionv@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class SamplePlugin extends Plugin
{
// Versions start at 0.1.0 in Semver
const PLUGIN_VERSION = '0.1.0';
/**
* Plugins are configured using public instance attributes. To set
* their values, site administrators use this syntax:
*
* addPlugin('Sample', ['attr1' => 'foo', 'attr2' => 'bar']);
*
* The same plugin class can be initialized multiple times with different
* arguments:
*
* addPlugin('EmailNotify', ['sendTo' => 'evan@status.net']);
* addPlugin('EmailNotify', ['sendTo' => 'brionv@status.net']);
*
*/
public $attr1 = null;
public $attr2 = null;
/**
* Initializer for this plugin
*
* Plugins overload this method to do any initialization they need,
* like connecting to remote servers or creating paths or so on.
*
* @return bool hook value; true means continue processing, false means stop.
*/
public function initialize(): bool
{
return true;
}
/**
* Cleanup for this plugin
*
* Plugins overload this method to do any cleanup they need,
* like disconnecting from remote servers or deleting temp files or so on.
*
* @return bool hook value; true means continue processing, false means stop.
*/
public function cleanup(): bool
{
return true;
}
/**
* Database schema setup
*
* Plugins can add their own tables to the StatusNet database. Plugins
* should use StatusNet's schema interface to add or delete tables. The
* ensureTable() method provides an easy way to ensure a table's structure
* and availability.
*
* By default, the schema is checked every time StatusNet is run (say, when
* a Web page is hit). Admins can configure their systems to only check the
* schema when the checkschema.php script is run, greatly improving performance.
* However, they need to remember to run that script after installing or
* upgrading a plugin!
*
* @return bool hook value; true means continue processing, false means stop.
* @see Schema
* @see ColumnDef
*/
public function onCheckSchema(): bool
{
$schema = Schema::get();
// For storing user-submitted flags on profiles
$schema->ensureTable('user_greeting_count', User_greeting_count::schemaDef());
return true;
}
/**
* Map URLs to actions
*
* This event handler lets the plugin map URLs on the site to actions (and
* thus an action handler class). Note that the action handler class for an
* action will be named 'FoobarAction', where action = 'foobar'. The class
* must be loaded in the onAutoload() method.
*
* @param URLMapper $m path-to-action mapper
*
* @return bool hook value; true means continue processing, false means stop.
* @throws Exception If it can't connect our required routes
*/
public function onRouterInitialized(URLMapper $m): bool
{
$m->connect(
'main/hello',
['action' => 'hello']
);
return true;
}
/**
* Modify the default menu to link to our custom action
*
* Using event handlers, it's possible to modify the default UI for pages
* almost without limit. In this method, we add a menu item to the default
* primary menu for the interface to link to our action.
*
* The Action class provides a rich set of events to hook, as well as output
* methods.
*
* @param Action $action The current action handler. Use this to
* do any output.
*
* @return bool hook value; true means continue processing, false means stop.
*
* @throws Exception
* @see Action
*/
public function onEndPrimaryNav(Action $action): bool
{
// common_local_url() gets the correct URL for the action name
// we provide
$action->menuItem(
common_local_url('hello'),
// TRANS: Menu item in sample plugin.
_m('Hello'),
// TRANS: Menu item title in sample plugin.
_m('A warm greeting'),
false,
'nav_hello'
);
return true;
}
/**
* Plugin version information/meta-data
*
* @param array $versions
* @return bool hook true
* @throws Exception
*/
public function onPluginVersion(array &$versions): bool
{
$versions[] = [
'name' => 'Sample',
'version' => self::PLUGIN_VERSION,
'author' => 'Brion Vibber, Evan Prodromou',
'homepage' => GNUSOCIAL_ENGINE_REPO_URL . 'tree/master/plugins/Sample',
'rawdescription' =>
// TRANS: Plugin description.
_m('A sample plugin to show basics of development for new hackers.')
];
return true;
}
}

View File

@@ -1,180 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Give a warm greeting to our friendly user
*
* @package GNU social
* @author Brion Vibber <brionv@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* This sample action shows some basic ways of doing output in an action
* class.
*
* Action classes have several output methods that they override from
* the parent class.
*
* @category Sample
* @package GNU social
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class HelloAction extends Action
{
public $user = null;
public $gc = null;
/**
* Take arguments for running
*
* This method is called first, and it lets the action class get
* all its arguments and validate them. It's also the time
* to fetch any relevant data from the database.
*
* Action classes should run parent::prepare($args) as the first
* line of this method to make sure the default argument-processing
* happens.
*
* @param array $args $_REQUEST args
*
* @return bool success flag
* @throws ClientException
*/
public function prepare(array $args = [])
{
parent::prepare($args);
$this->user = common_current_user();
if (!empty($this->user)) {
$this->gc = User_greeting_count::inc($this->user->getID());
}
return true;
}
/**
* Handle request
*
* This is the main method for handling a request. Note that
* most preparation should be done in the prepare() method;
* by the time handle() is called the action should be
* more or less ready to go.
*
* @return void
* @throws ClientException
* @throws ReflectionException
* @throws ServerException
*/
public function handle()
{
parent::handle();
$this->showPage();
}
/**
* Title of this page
*
* Override this method to show a custom title.
*
* @return string Title of the page
* @throws Exception
*/
public function title()
{
if (empty($this->user)) {
// TRANS: Page title for sample plugin.
return _m('Hello');
} else {
// TRANS: Page title for sample plugin. %s is a user nickname.
return sprintf(_m('Hello, %s!'), $this->user->getNickname());
}
}
/**
* Show content in the content area
*
* The default StatusNet page has a lot of decorations: menus,
* logos, tabs, all that jazz. This method is used to show
* content in the content area of the page; it's the main
* thing you want to overload.
*
* This method also demonstrates use of a plural localized string.
*
* @return void
* @throws Exception
*/
public function showContent()
{
if (empty($this->user)) {
$this->element(
'p',
['class' => 'greeting'],
// TRANS: Message in sample plugin.
_m('Hello, stranger!')
);
} else {
$this->element(
'p',
['class' => 'greeting'],
// TRANS: Message in sample plugin. %s is a user nickname.
sprintf(_m('Hello, %s'), $this->user->getNickname())
);
$this->element(
'p',
['class' => 'greeting_count'],
// TRANS: Message in sample plugin.
// TRANS: %d is the number of times a user is greeted.
sprintf(
_m(
'I have greeted you %d time.',
'I have greeted you %d times.',
$this->gc->greeting_count
),
$this->gc->greeting_count
)
);
}
}
/**
* Return true if read only.
*
* Some actions only read from the database; others read and write.
* The simple database load-balancer built into StatusNet will
* direct read-only actions to database mirrors (if they are configured),
* and read-write actions to the master database.
*
* This defaults to false to avoid data integrity issues, but you
* should make sure to overload it for performance gains.
*
* @param array $args other arguments, if RO/RW status depends on them.
*
* @return bool is read only action?
*/
public function isReadOnly($args)
{
return false;
}
}

View File

@@ -1,120 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Data class for counting greetings
*
* @package GNUsocial
* @author Brion Vibber <brionv@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* We use the DB_DataObject framework for data classes in GNU social. Each
* table maps to a particular data class, making it easier to manipulate
* data.
*
* Data classes should extend Memcached_DataObject, the (slightly misnamed)
* extension of DB_DataObject that provides caching, internationalization,
* and other bits of good functionality to StatusNet-specific data classes.
*
* @category Action
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*
* @see DB_DataObject
*/
class User_greeting_count extends Managed_DataObject
{
public $__table = 'user_greeting_count'; // table name
public $user_id; // int(4) primary_key not_null
public $greeting_count; // int(4)
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return [
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user id'],
'greeting_count' => ['type' => 'int', 'not null' => true, 'description' => 'the greeting count'],
'created' => ['type' => 'datetime', 'description' => 'date this record was created'],
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
],
'primary key' => ['user_id'],
'foreign keys' => [
'user_greeting_count_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
/**
* Increment a user's greeting count and return instance
*
* This method handles the ins and outs of creating a new greeting_count for a
* user or fetching the existing greeting count and incrementing its value.
*
* @param integer $user_id ID of the user to get a count for
*
* @return User_greeting_count instance for this user, with count already incremented.
* @throws Exception
*/
public static function inc($user_id)
{
$gc = User_greeting_count::getKV('user_id', $user_id);
if (empty($gc)) {
$gc = new User_greeting_count();
$gc->user_id = $user_id;
$gc->greeting_count = 1;
$result = $gc->insert();
if (!$result) {
// TRANS: Exception thrown when the user greeting count could not be saved in the database.
// TRANS: %d is a user ID (number).
throw new Exception(sprintf(
_m('Could not save new greeting count for %d.'),
$user_id
));
}
} else {
$orig = clone($gc);
++$gc->greeting_count;
$result = $gc->update($orig);
if (!$result) {
// TRANS: Exception thrown when the user greeting count could not be saved in the database.
// TRANS: %d is a user ID (number).
throw new Exception(sprintf(
_m('Could not increment greeting count for %d.'),
$user_id
));
}
}
return $gc;
}
}

View File

@@ -164,18 +164,26 @@ The ones that you may want to set are listed below for clarity.
* `database` (string, required, default null): a DSN (Data Source Name) for your * `database` (string, required, default null): a DSN (Data Source Name) for your
GNU social database. This is in the format GNU social database. This is in the format
'protocol://username:password@hostname/databasename', where 'protocol' is 'protocol://username:password@hostname/databasename', where 'protocol' is '
'mysqli' or 'pgsql' or 'mysql', 'username' is the username, 'password' is mysql' or 'mysqli' (or possibly 'postgresql', if you really know what
the password, and etc. you're doing), 'username' is the username, 'password' is the password,
and etc.
* `ini_yourdbname` (string, default null): if your database is not named 'statusnet', * `ini_yourdbname` (string, default null): if your database is not named 'statusnet',
you'll need to set this to point to the location of the statusnet.ini file. you'll need to set this to point to the location of the statusnet.ini file.
Note that the real name of your database should go in there, not literally Note that the real name of your database should go in there, not literally
'yourdbname'. 'yourdbname'.
* `type` (enum["mysql", "pgsql"], default 'mysql'): Used for certain * `db_driver`(enum['DB','MDB2'], default null): You can try changing this to
database-specific optimization code. Assumes mysql if not set. "mysql" 'MDB2' to use the other driver type for DB_DataObject, but note that it
covers MariaDB, Oracle MySQL, mysqli or otherwise. breaks the OpenID libraries, which only support PEAR::DB.
* `quote_identifiers`(boolean, default false): Set this to true if you're using
postgresql.
* `type` (enum["mysql", "postgresql"], default 'mysql'): Used for certain
database-specific optimization code. Assumes mysql if not set. MySQL also
covers MySQLi and MariaDB.
* `mirror` (array, default null): you can set this to an array of DSNs, in the * `mirror` (array, default null): you can set this to an array of DSNs, in the
format of the above 'database' value. If it's set, certain read-only format of the above 'database' value. If it's set, certain read-only
@@ -224,7 +232,7 @@ sending out SMS email or XMPP messages, for off-line processing. See
* `enabled` (boolean, default false): Whether to uses queues. * `enabled` (boolean, default false): Whether to uses queues.
* `daemon` (boolean, default false): Whether to use queuedaemon. False means * `daemon` (boolean, default false): Wather to use queuedaemon. False means
you'll use OpportunisticQM plugin. you'll use OpportunisticQM plugin.
* `subsystem` (enum["db", "stomp"], default 'db'): Which kind of queueserver to * `subsystem` (enum["db", "stomp"], default 'db'): Which kind of queueserver to
@@ -679,7 +687,7 @@ set too low (it's optional, so it may not be there at all).
* `file_quota`: maximum size for a single file upload in bytes. A user can send * `file_quota`: maximum size for a single file upload in bytes. A user can send
any amount of notices with attachments as long as each attachment any amount of notices with attachments as long as each attachment
is smaller than file_quota. Defaults to PHP's configured upload limit. is smaller than file_quota.
* `user_quota`: total size in bytes a user can store on this server. Each user * `user_quota`: total size in bytes a user can store on this server. Each user
can store any number of files as long as their total size does can store any number of files as long as their total size does
@@ -717,28 +725,6 @@ set too low (it's optional, so it may not be there at all).
* `filename_base`: for new files, choose one: 'upload', 'hash'. Defaults to hash. * `filename_base`: for new files, choose one: 'upload', 'hash'. Defaults to hash.
* `memory_limit`: PHP's memory limit to use temporarily when handling images. Defaults to `1024M`.
* `prefer_remote`: when a user uploads a file, if the first time this file was
retrieved was from an URL, prefer redirect to the attachment with the first known URL.
thumbnail
-------------------------------------------------------------------------------
The software lets users upload media with their notes. You can configure
the way thumbnails are generated for them.
* `dir`: Where to store, defaults to `File::path('thumb')` (equivalent to `['attachments']['dir']/thumb/`).
* `path`: URL path, relative to the server, to find thumbnails. Defaults to `File::url('thumb/$filename')` (equivalent to `['attachments']['path']/thumb/`).
* `server`: Only used if `['thumbnail']['path']` is NOT empty. In which case it defaults to `['site']['server']`, schema is decided from `GNUsocial::useHTTPS()`
* `crop`: Crop to the size (not preserving aspect ratio). Defaults to false.
* `maxsize`: Thumbs with an edge larger than this will not be generated. Defaults to 1000.
* `width`: Max width for the thumbnail. Defaults to 450.
* `height`: Max height for the thumbnail. Defaults to 600.
* `upscale`: Whether or not to scale smaller images up to larger thumbnail sizes. Defaults to false.
* `animated`: `null` means use file as thumbnail. `false` means that a still frame can be used. `true` requires `ImageMagickPlugin`. Defaults to false.
group group
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -762,9 +748,11 @@ search
Some stuff for search. Some stuff for search.
* `type`: type of search. Ignored if PostgreSQL or Sphinx are enabled. Can either * `type`: type of search. Ignored if PostgreSQL or Sphinx are enabled. Can either
be 'like' or 'fulltext' (default). The latter is faster and more efficient be 'fulltext' or 'like' (default). The former is faster and more efficient
but if your storage engine of choice does not support it, then feel free to but requires the lame old MyISAM engine for MySQL. The latter
choose 'like', but it could be miserably slow on large databases. will work with InnoDB but could be miserably slow on large
systems. We'll probably add another type sometime in the future,
with our own indexing system (maybe like MediaWiki's).
sessions sessions

View File

@@ -6,15 +6,7 @@ server {
server_name social.example.org; server_name social.example.org;
# redirect all traffic to HTTPS # redirect all traffic to HTTPS
return 301 https://$host$request_uri; rewrite ^ https://$host$request_uri? permanent;
}
map $sent_http_content_type $gnusocial_expires_policy {
default off;
text/css 30d;
application/javascript 30d;
~image/ 30d;
~video/ 30d;
} }
server { server {
@@ -39,36 +31,22 @@ server {
# Index # Index
index index.php; index index.php;
# Enable browser caching for JS, CSS, images, audio, video
expires $gnusocial_expires_policy;
# X-Accel/X-Sendfile. Still needs to be enabled in the config # X-Accel/X-Sendfile. Still needs to be enabled in the config
location ^~ /file { location /file {
internal; internal;
# FIXME: Change "/path/to/gnusocial/root/" to the folder where # FIXME: Change "/path/to/gnusocial/root/" to the folder where
# attachments are stored (normally the same as the site root) # attachments are stored (normally the same as the site root)
root /path/to/gnusocial/root/; root /path/to/gnusocial/root/;
# Enable compression for images, audio, video to save bandwidth
# gzip on;
# gzip_comp_level 4;
} }
# PHP # PHP
# FIXME: Change "php7.X" to your version of fpm
location ~ ^/(index|install)\.php(/.*)?$ { location ~ ^/(index|install)\.php(/.*)?$ {
#location ^~ /index.php { #location ^~ /index.php {
include fastcgi_params; include fastcgi_params;
include snippets/fastcgi-php.conf;
fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_pass unix:/run/php/php-fpm.sock;
set $path_info $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $request_filename;
try_files $fastcgi_script_name =404;
fastcgi_pass unix:/run/php/php7.X-fpm.sock;
fastcgi_index index.php;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
} }
# Don't allow any PHP file other than index.php to be executed # Don't allow any PHP file other than index.php to be executed
@@ -83,11 +61,6 @@ server {
try_files $uri $uri/ @index_handler; try_files $uri $uri/ @index_handler;
} }
# If avatars are located at /path/to/gnusocial/root/file (default)
location ^~ /avatar {
rewrite ^(.*)$ /file/$1 last;
}
# Fancy URLs # Fancy URLs
error_page 404 @index_handler; error_page 404 @index_handler;
location @index_handler { location @index_handler {
@@ -112,4 +85,13 @@ server {
# client_max_body_size 15M; # client_max_body_size 15M;
# client_body_buffer_size 128k; # client_body_buffer_size 128k;
# gzip_vary on; # gzip_vary on;
#
# location ~* \.(?:css|js|woff|svg|gif|png|webp|ttf|ico|jpe?g)$ {
# gzip on;
# gzip_comp_level 4;
# add_header Cache-Control "public";
# expires 30d;
# access_log off;
# log_not_found off;
# }
} }

View File

@@ -27,8 +27,8 @@ PHP modules
The following software packages are *required* for this software to The following software packages are *required* for this software to
run correctly. run correctly.
- PHP 7.3+ - PHP 7+ PHP7.x is also supported.
- MariaDB 10.3+ - MariaDB 5+ MariaDB 10.x is also supported.
- Web server Apache, lighttpd and nginx will all work. CGI mode is - Web server Apache, lighttpd and nginx will all work. CGI mode is
recommended and also some variant of 'suexec' (or a recommended and also some variant of 'suexec' (or a
proper setup php-fpm pool) proper setup php-fpm pool)
@@ -50,6 +50,7 @@ functional setup of GNU social:
- php-opcache Improved PHP performance by precompilation - php-opcache Improved PHP performance by precompilation
- php-readline For interactive scripts - php-readline For interactive scripts
- php-xml XML parser - php-xml XML parser
- php-ds Faster data structures
NOTE: Some distros require manual enabling in the relevant php.ini for some modules. NOTE: Some distros require manual enabling in the relevant php.ini for some modules.
@@ -69,6 +70,7 @@ For some functionality, you will also need the following extensions:
- gettext For multiple languages. Default on many PHP installs; - gettext For multiple languages. Default on many PHP installs;
will be emulated if not present. will be emulated if not present.
- exif For thumbnails to be properly oriented. - exif For thumbnails to be properly oriented.
- php-ds For faster data structures; will be emulated if not present.
You may also experience better performance from your site if you configure You may also experience better performance from your site if you configure
a PHP cache/accelerator. Most distributions come with "opcache" support. a PHP cache/accelerator. Most distributions come with "opcache" support.

View File

@@ -115,17 +115,15 @@ to install the development version of GNU social.
To get it, use the git version control tool To get it, use the git version control tool
<http://git-scm.com/> like so: <http://git-scm.com/> like so:
git clone https://notabug.org/diogo/gnu-social.git git clone git@notabug.org:diogo/gnu-social.git
In the current phase of development it is probably In the current phase of development it is probably
recommended to use git as a means to stay up to date recommended to use git as a means to stay up to date
with the source code. You can choose between these with the source code. You can choose between these
branches: branches:
* 1.20.x "oldstable", few updates, well tested coded ( **recommended** ) * 1.20.x "oldstable", few updates, well tested coded
* master "stable", usually working well (should be safe) * master "stable", usually working well
* nightly "testing", most updates, not always working as expected (can be dangerous) * nightly "testing", most updates, not always working as expected
**IMPORTANT: We force push to the nightly branch, the nightly branch is intended for GNU social developers only.**
To keep it up-to-date, use `git pull`. Watch for conflicts! To keep it up-to-date, use `git pull`. Watch for conflicts!

View File

@@ -1,50 +0,0 @@
# GNU social v2.0.0 - THIS. IS. GNU SOCIAL!!!
Release name chosen after 300 by Frank Miller where the main protagonist Leonidas, King of Sparta, declines peace with the
Persians, after being disrespected, by shouting at the Persian Messenger "This is Sparta!" and kicking him into a large well
proceeded by the killing of the other Persian messengers.
## For users/sysadmins
### Web server changes
- GS is now structurely divided in includes and public
- New media handling system, new important settings, refer to CONFIGURE doc and web server conf
- `$config['site']['x-static-delivery']`
- You must also review the [attachments section of CONFIGURE](https://notabug.org/diogo/gnu-social/src/new_modules_system/DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE.md#attachments).
- OEmbed upgraded to Embed plugin (and now we provide Open Graph information too)
- Composer was integrated
### Functionality
- Restored broken built-in plugins
- A more powerful Plugins management tool for sysadmins
### Federation
- Added ActivityPub support
- Enabled the search box to import remote notices and profiles
- Direct messages
### Load and Storage
- Improved Cronish
- Run session garbage collection
- Cleanup Email Registration
- New queues system
- Support for Redis was added
- Support for PostgreSQL was added
## For developers
### APIs
- New Internal Session Handler and consequently a new API, migration should be simple enough
- Dropped support for StatusNet plugins, devs should now use GNUsocial class instead
### Modules
- Composer was integrated
- GS is now structurely divided in includes and public
- A more powerful Plugins management tool for sysadmins
Now plugins can be installed via the sysadmin UI. Therefore, now you should package your plugins either in tar or zip. The
package name must be the same as the plugin's internal name. For example, a plugin
named `Chuck Norris (social@chuck.norris)` must be in a file named: `ChuckNorris.tar`.
Inside there MUST be two directories, one named 'includes' with everything that should be unpacked
in `local/plugins/{plugin_name}` and another named 'public' with everything that should be unpacked
in `public/local/plugins/{plugin_name}`.

15
TODO.md
View File

@@ -1,15 +0,0 @@
# TODO
Hi! Thank you for your interest in contributing, please refer to
[DOCUMENTATION/DEVELOPERS](https://notabug.org/diogo/gnu-social/src/nightly/DOCUMENTATION/DEVELOPERS)
to learn how you can contribute.
Our roadmap is available in the following Kanban board:
[Kanban Board](https://kanban.diogo.site/?controller=BoardViewController&action=readonly&token=03795efb8138c4e7661a900c234c0df1bc3fc03cdfcda8619cd5d0e666de).
There are more pending tasks/ideas to implement in this
[repo's issues](https://notabug.org/diogo/gnu-social/issues).
So consider the issue tracker to be the full backlog, in the kanban board it's just what the
[development team](https://notabug.org/diogo/gnu-social/src/nightly/CREDITS.md)
is working on.

View File

@@ -1,38 +1,42 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Site access administration panel * Site access administration panel
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings * @category Settings
* @package GNUsocial * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc. * @copyright 2010 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Administer site access settings * Administer site access settings
* *
* @category Admin * @category Admin
* @package GNUsocial * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class AccessadminpanelAction extends AdminPanelAction class AccessadminpanelAction extends AdminPanelAction
{ {
@@ -41,7 +45,7 @@ class AccessadminpanelAction extends AdminPanelAction
* *
* @return string page title * @return string page title
*/ */
public function title() function title()
{ {
// TRANS: Page title for Access admin panel that allows configuring site access. // TRANS: Page title for Access admin panel that allows configuring site access.
return _('Access'); return _('Access');
@@ -52,7 +56,7 @@ class AccessadminpanelAction extends AdminPanelAction
* *
* @return string instructions * @return string instructions
*/ */
public function getInstructions() function getInstructions()
{ {
// TRANS: Page notice. // TRANS: Page notice.
return _('Site access settings'); return _('Site access settings');
@@ -63,7 +67,7 @@ class AccessadminpanelAction extends AdminPanelAction
* *
* @return void * @return void
*/ */
public function showForm() function showForm()
{ {
$form = new AccessAdminPanelForm($this); $form = new AccessAdminPanelForm($this);
$form->show(); $form->show();
@@ -75,7 +79,7 @@ class AccessadminpanelAction extends AdminPanelAction
* *
* @return void * @return void
*/ */
public function saveSettings() function saveSettings()
{ {
static $booleans = array('site' => array('private', 'inviteonly', 'closed'), static $booleans = array('site' => array('private', 'inviteonly', 'closed'),
'public' => array('localonly')); 'public' => array('localonly'));
@@ -88,7 +92,7 @@ class AccessadminpanelAction extends AdminPanelAction
$config = new Config(); $config = new Config();
$config->query('START TRANSACTION'); $config->query('BEGIN');
foreach ($booleans as $section => $parts) { foreach ($booleans as $section => $parts) {
foreach ($parts as $setting) { foreach ($parts as $setting) {
@@ -109,7 +113,7 @@ class AccessAdminPanelForm extends AdminForm
* *
* @return int ID of the form * @return int ID of the form
*/ */
public function id() function id()
{ {
return 'form_site_admin_panel'; return 'form_site_admin_panel';
} }
@@ -119,7 +123,7 @@ class AccessAdminPanelForm extends AdminForm
* *
* @return string class of the form * @return string class of the form
*/ */
public function formClass() function formClass()
{ {
return 'form_settings'; return 'form_settings';
} }
@@ -129,7 +133,7 @@ class AccessAdminPanelForm extends AdminForm
* *
* @return string URL of the action * @return string URL of the action
*/ */
public function action() function action()
{ {
return common_local_url('accessadminpanel'); return common_local_url('accessadminpanel');
} }
@@ -139,7 +143,7 @@ class AccessAdminPanelForm extends AdminForm
* *
* @return void * @return void
*/ */
public function formData() function formData()
{ {
$this->out->elementStart('fieldset', array('id' => 'settings_admin_account_access')); $this->out->elementStart('fieldset', array('id' => 'settings_admin_account_access'));
// TRANS: Form legend for registration form. // TRANS: Form legend for registration form.
@@ -150,24 +154,18 @@ class AccessAdminPanelForm extends AdminForm
// TRANS: Checkbox instructions for admin setting "Invite only". // TRANS: Checkbox instructions for admin setting "Invite only".
$instructions = _('Make registration invitation only.'); $instructions = _('Make registration invitation only.');
// TRANS: Checkbox label for configuring site as invite only. // TRANS: Checkbox label for configuring site as invite only.
$this->out->checkbox( $this->out->checkbox('inviteonly', _('Invite only'),
'inviteonly',
_('Invite only'),
(bool) $this->value('inviteonly'), (bool) $this->value('inviteonly'),
$instructions $instructions);
);
$this->unli(); $this->unli();
$this->li(); $this->li();
// TRANS: Checkbox instructions for admin setting "Closed" (no new registrations). // TRANS: Checkbox instructions for admin setting "Closed" (no new registrations).
$instructions = _('Disable new registrations.'); $instructions = _('Disable new registrations.');
// TRANS: Checkbox label for disabling new user registrations. // TRANS: Checkbox label for disabling new user registrations.
$this->out->checkbox( $this->out->checkbox('closed', _('Closed'),
'closed',
_('Closed'),
(bool) $this->value('closed'), (bool) $this->value('closed'),
$instructions $instructions);
);
$this->unli(); $this->unli();
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@@ -175,7 +173,7 @@ class AccessAdminPanelForm extends AdminForm
// Public access settings (login requirements for feeds etc.) // Public access settings (login requirements for feeds etc.)
$this->out->elementStart('fieldset', ['id' => 'settings_admin_public_access']); $this->out->elementStart('fieldset', array('id' => 'settings_admin_public_access'));
// TRANS: Form legend for registration form. // TRANS: Form legend for registration form.
$this->out->element('legend', null, _('Feed access')); $this->out->element('legend', null, _('Feed access'));
$this->out->elementStart('ul', 'form_data'); $this->out->elementStart('ul', 'form_data');
@@ -183,24 +181,18 @@ class AccessAdminPanelForm extends AdminForm
// TRANS: Checkbox instructions for admin setting "Private". // TRANS: Checkbox instructions for admin setting "Private".
$instructions = _('Prohibit anonymous users (not logged in) from viewing site?'); $instructions = _('Prohibit anonymous users (not logged in) from viewing site?');
// TRANS: Checkbox label for prohibiting anonymous users from viewing site. // TRANS: Checkbox label for prohibiting anonymous users from viewing site.
$this->out->checkbox( $this->out->checkbox('private', _m('LABEL', 'Private'),
'private',
_m('LABEL', 'Private'),
(bool) $this->value('private'), (bool) $this->value('private'),
$instructions $instructions);
);
$this->unli(); $this->unli();
$this->li(); $this->li();
// TRANS: Description of the full network notice stream views.. // TRANS: Description of the full network notice stream views..
$instructions = _('The full network view includes (public) remote notices which may be unrelated to local conversations.'); $instructions = _('The full network view includes (public) remote notices which may be unrelated to local conversations.');
// TRANS: Checkbox label for hiding remote network posts if they have not been interacted with locally. // TRANS: Checkbox label for hiding remote network posts if they have not been interacted with locally.
$this->out->checkbox( $this->out->checkbox('localonly', _('Restrict full network view to accounts'),
'localonly',
_('Restrict full network view to accounts'),
(bool) $this->value('localonly', 'public'), (bool) $this->value('localonly', 'public'),
$instructions $instructions);
);
$this->unli(); $this->unli();
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@@ -212,7 +204,7 @@ class AccessAdminPanelForm extends AdminForm
* *
* @return void * @return void
*/ */
public function formActions() function formActions()
{ {
// TRANS: Button title to save access settings in site admin panel. // TRANS: Button title to save access settings in site admin panel.
$title = _('Save access settings.'); $title = _('Save access settings.');

View File

@@ -31,7 +31,7 @@ if (!defined('STATUSNET')) {
exit(1); exit(1);
} }
require_once INSTALLDIR . '/lib/profile/togglepeopletag.php'; require_once INSTALLDIR . '/lib/togglepeopletag.php';
/** /**
* *

View File

@@ -1,45 +1,55 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Show the newest groups * Show the newest groups
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Craig Andrews <candrews@integralblue.com> * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com> * @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc. * @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('STATUSNET')) {
exit(1);
}
/** /**
* Returns of the lastest 20 groups for the site * Returns of the lastest 20 groups for the site
* *
* @copyright 2009 StatusNet, Inc. * @category API
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @package StatusNet
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ApiGroupListAllAction extends ApiPrivateAuthAction class ApiGroupListAllAction extends ApiPrivateAuthAction
{ {
public $groups = null; var $groups = null;
/** /**
* Take arguments for running * Take arguments for running
@@ -48,7 +58,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return boolean success flag * @return boolean success flag
*/ */
public function prepare(array $args = []) function prepare(array $args = array())
{ {
parent::prepare($args); parent::prepare($args);
@@ -67,7 +77,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return void * @return void
*/ */
public function handle() function handle()
{ {
parent::handle(); parent::handle();
@@ -80,7 +90,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
// TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name. // TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name.
$subtitle = sprintf(_("groups on %s"), $sitename); $subtitle = sprintf(_("groups on %s"), $sitename);
switch ($this->format) { switch($this->format) {
case 'xml': case 'xml':
$this->showXmlGroups($this->groups); $this->showXmlGroups($this->groups);
break; break;
@@ -118,23 +128,25 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return array groups * @return array groups
*/ */
public function getGroups() function getGroups()
{ {
$qry = 'SELECT user_group.* '.
'from user_group join local_group on user_group.id = local_group.group_id '.
'order by created desc ';
$offset = intval($this->page - 1) * intval($this->count);
$limit = intval($this->count);
if (common_config('db', 'type') == 'pgsql') {
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else {
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
}
$group = new User_group(); $group = new User_group();
$group->selectAdd(); $group->query($qry);
$group->selectAdd('user_group.*');
$group->joinAdd(['id', 'local_group:group_id']);
$group->orderBy('user_group.created DESC, user_group.id DESC');
$offset = ((int) $this->page - 1) * (int) $this->count; $groups = array();
$group->limit($offset, $this->count);
$groups = [];
if ($group->find()) {
while ($group->fetch()) { while ($group->fetch()) {
$groups[] = clone $group; $groups[] = clone($group);
}
} }
return $groups; return $groups;
@@ -147,7 +159,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return boolean true * @return boolean true
*/ */
public function isReadOnly($args) function isReadOnly($args)
{ {
return true; return true;
} }
@@ -157,7 +169,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return string datestamp of the site's latest group * @return string datestamp of the site's latest group
*/ */
public function lastModified() function lastModified()
{ {
if (!empty($this->groups) && (count($this->groups) > 0)) { if (!empty($this->groups) && (count($this->groups) > 0)) {
return strtotime($this->groups[0]->created); return strtotime($this->groups[0]->created);
@@ -174,9 +186,10 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
* *
* @return string etag * @return string etag
*/ */
public function etag() function etag()
{ {
if (!empty($this->groups) && (count($this->groups) > 0)) { if (!empty($this->groups) && (count($this->groups) > 0)) {
$last = count($this->groups) - 1; $last = count($this->groups) - 1;
return '"' . implode( return '"' . implode(

View File

@@ -1,38 +1,44 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Update a group's profile * Update a group's profile
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc. * @copyright 2010 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('STATUSNET')) {
exit(1);
}
/** /**
* API analog to the group edit page * API analog to the group edit page
* *
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ApiGroupProfileUpdateAction extends ApiAuthAction class ApiGroupProfileUpdateAction extends ApiAuthAction
{ {
@@ -94,21 +100,20 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
$this->clientError(_('You must be an admin to edit the group.'), 403); $this->clientError(_('You must be an admin to edit the group.'), 403);
} }
$this->group->query('START TRANSACTION'); $this->group->query('BEGIN');
$orig = clone($this->group); $orig = clone($this->group);
try { try {
if (common_config('profile', 'changenick') == true && $this->group->nickname !== $this->nickname) { if (common_config('profile', 'changenick') == true && $this->group->nickname !== $this->nickname) {
try { try {
$this->group->nickname = Nickname::normalize($this->nickname, true); $this->group->nickname = Nickname::normalize($this->nickname, true);
} catch (NicknameException $e) { } catch (NicknameException $e) {
throw new ApiValidationException($e->getMessage()); throw new ApiValidationException($e->getMessage());
} }
$this->group->mainpage = common_local_url( $this->group->mainpage = common_local_url('showgroup',
'showgroup', array('nickname' => $this->group->nickname));
['nickname' => $this->group->nickname]
);
} }
if (!empty($this->fullname)) { if (!empty($this->fullname)) {
@@ -130,6 +135,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
$this->validateLocation(); $this->validateLocation();
$this->group->location = $this->location; $this->group->location = $this->location;
} }
} catch (ApiValidationException $ave) { } catch (ApiValidationException $ave) {
$this->clientError($ave->getMessage(), 400); $this->clientError($ave->getMessage(), 400);
} }
@@ -161,7 +167,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
$this->group->query('COMMIT'); $this->group->query('COMMIT');
switch ($this->format) { switch($this->format) {
case 'xml': case 'xml':
$this->showSingleXmlGroup($this->group); $this->showSingleXmlGroup($this->group);
break; break;
@@ -174,7 +180,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
} }
} }
public function validateHomepage() function validateHomepage()
{ {
if (!is_null($this->homepage) if (!is_null($this->homepage)
&& (strlen($this->homepage) > 0) && (strlen($this->homepage) > 0)
@@ -186,7 +192,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
} }
} }
public function validateFullname() function validateFullname()
{ {
if (!is_null($this->fullname) && mb_strlen($this->fullname) > 255) { if (!is_null($this->fullname) && mb_strlen($this->fullname) > 255) {
throw new ApiValidationException( throw new ApiValidationException(
@@ -196,21 +202,19 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
} }
} }
public function validateDescription() function validateDescription()
{ {
if (User_group::descriptionTooLong($this->description)) { if (User_group::descriptionTooLong($this->description)) {
// TRANS: API validation exception thrown when description does not validate. // TRANS: API validation exception thrown when description does not validate.
// TRANS: %d is the maximum description length and used for plural. // TRANS: %d is the maximum description length and used for plural.
throw new ApiValidationException(sprintf( throw new ApiValidationException(sprintf(_m('Description is too long (maximum %d character).',
_m('Description is too long (maximum %d character).',
'Description is too long (maximum %d characters).', 'Description is too long (maximum %d characters).',
User_group::maxDescription()), User_group::maxDescription()),
User_group::maxDescription() User_group::maxDescription()));
));
} }
} }
public function validateLocation() function validateLocation()
{ {
if (!is_null($this->location) && mb_strlen($this->location) > 255) { if (!is_null($this->location) && mb_strlen($this->location) > 255) {
throw new ApiValidationException( throw new ApiValidationException(
@@ -220,13 +224,11 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
} }
} }
public function validateAliases() function validateAliases()
{ {
try { try {
$aliases = array_map( $aliases = array_map(array('Nickname', 'normalize'),
['Nickname', 'normalize'], array_unique(preg_split('/[\s,]+/', $this->aliasstring)));
array_unique(preg_split('/[\s,]+/', $this->aliasstring))
);
} catch (NicknameException $e) { } catch (NicknameException $e) {
throw new ApiValidationException(sprintf('Error processing aliases: %s', $e->getMessage())); throw new ApiValidationException(sprintf('Error processing aliases: %s', $e->getMessage()));
} }
@@ -234,12 +236,10 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
if (count($aliases) > common_config('group', 'maxaliases')) { if (count($aliases) > common_config('group', 'maxaliases')) {
// TRANS: API validation exception thrown when aliases do not validate. // TRANS: API validation exception thrown when aliases do not validate.
// TRANS: %d is the maximum number of aliases and used for plural. // TRANS: %d is the maximum number of aliases and used for plural.
throw new ApiValidationException(sprintf( throw new ApiValidationException(sprintf(_m('Too many aliases! Maximum %d allowed.',
_m('Too many aliases! Maximum %d allowed.',
'Too many aliases! Maximum %d allowed.', 'Too many aliases! Maximum %d allowed.',
common_config('group', 'maxaliases')), common_config('group', 'maxaliases')),
common_config('group', 'maxaliases') common_config('group', 'maxaliases')));
));
} }
return $aliases; return $aliases;

View File

@@ -30,7 +30,7 @@ if (!defined('STATUSNET')) {
exit(1); exit(1);
} }
require_once INSTALLDIR . '/lib/api/apilistusers.php'; require_once INSTALLDIR . '/lib/apilistusers.php';
class ApiListMembersAction extends ApiListUsersAction class ApiListMembersAction extends ApiListUsersAction
{ {

View File

@@ -29,7 +29,7 @@ if (!defined('STATUSNET')) {
exit(1); exit(1);
} }
require_once INSTALLDIR . '/lib/api/apilistusers.php'; require_once INSTALLDIR . '/lib/apilistusers.php';
class ApiListSubscribersAction extends ApiListUsersAction class ApiListSubscribersAction extends ApiListUsersAction
{ {

View File

@@ -1,44 +1,48 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Upload an image via the API * Upload an image via the API
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API * @category API
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc. * @copyright 2010 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Upload an image via the API. Returns a shortened URL for the image * Upload an image via the API. Returns a shortened URL for the image
* to the user. Apparently modelled after a former Twitpic API. * to the user. Apparently modelled after a former Twitpic API.
* *
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ApiMediaUploadAction extends ApiAuthAction class ApiMediaUploadAction extends ApiAuthAction
{ {
protected $needPost = true; protected $needPost = true;
protected function prepare(array $args = []) protected function prepare(array $args=array())
{ {
parent::prepare($args); parent::prepare($args);
@@ -75,21 +79,20 @@ class ApiMediaUploadAction extends ApiAuthAction
$upload = MediaFile::fromUpload('media', $this->scoped); $upload = MediaFile::fromUpload('media', $this->scoped);
} catch (NoUploadedMediaException $e) { } catch (NoUploadedMediaException $e) {
common_debug('No media file was uploaded to the _FILES array'); common_debug('No media file was uploaded to the _FILES array');
$tempfile = new TemporaryFile('gs-mediaupload'); $fh = tmpfile();
if ($this->arg('media')) { if ($this->arg('media')) {
common_debug('Found media parameter which we hope contains a media file!'); common_debug('Found media parameter which we hope contains a media file!');
fwrite($tempfile->getResource(), $this->arg('media')); fwrite($fh, $this->arg('media'));
} elseif ($this->arg('media_data')) { } elseif ($this->arg('media_data')) {
common_debug('Found media_data parameter which we hope contains a base64-encoded media file!'); common_debug('Found media_data parameter which we hope contains a base64-encoded media file!');
fwrite($tempfile->getResource(), base64_decode($this->arg('media_data'))); fwrite($fh, base64_decode($this->arg('media_data')));
} else { } else {
common_debug('No media|media_data POST parameter was supplied'); common_debug('No media|media_data POST parameter was supplied');
unset($tempfile); fclose($fh);
throw $e; throw $e;
} }
common_debug('MediaFile importing the uploaded file with fromFileInfo'); common_debug('MediaFile importing the uploaded file with fromFilehandle');
fflush($tempfile->getResource()); $upload = MediaFile::fromFilehandle($fh, $this->scoped);
$upload = MediaFile::fromFileInfo($tempfile, $this->scoped);
} }
common_debug('MediaFile completed and saved us fileRecord with id=='._ve($upload->fileRecord->id)); common_debug('MediaFile completed and saved us fileRecord with id=='._ve($upload->fileRecord->id));
@@ -165,9 +168,9 @@ class ApiMediaUploadAction extends ApiAuthAction
/** /**
* Overrided clientError to show a more Twitpic-like error * Overrided clientError to show a more Twitpic-like error
* *
* @param string $msg an error message * @param String $msg an error message
*/ */
public function clientError($msg, $code = 400, $format = null) function clientError($msg, $code=400, $format=null)
{ {
$this->initDocument($this->format); $this->initDocument($this->format);
switch ($this->format) { switch ($this->format) {

View File

@@ -1,24 +1,26 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Show a notice (as a Twitter-style status) * Show a notice (as a Twitter-style status)
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Craig Andrews <candrews@integralblue.com> * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com> * @author Jeffery To <jeffery.to@gmail.com>
@@ -28,16 +30,17 @@
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc. * @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Returns the notice specified by id as a Twitter-style status and inline user * Returns the notice specified by id as a Twitter-style status and inline user
* *
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Craig Andrews <candrews@integralblue.com> * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com> * @author Jeffery To <jeffery.to@gmail.com>
@@ -45,12 +48,13 @@ defined('GNUSOCIAL') || die();
* @author Mike Cochrane <mikec@mikenz.geek.nz> * @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info> * @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ApiStatusesShowAction extends ApiPrivateAuthAction class ApiStatusesShowAction extends ApiPrivateAuthAction
{ {
public $notice_id = null; var $notice_id = null;
public $notice = null; var $notice = null;
/** /**
* Take arguments for running * Take arguments for running
@@ -127,7 +131,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
* *
* @return void * @return void
*/ */
public function showNotice() function showNotice()
{ {
switch ($this->format) { switch ($this->format) {
case 'xml': case 'xml':
@@ -154,9 +158,9 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
* @return boolean true * @return boolean true
*/ */
public function isReadOnly($args) function isReadOnly($args)
{ {
return in_array($_SERVER['REQUEST_METHOD'], ['GET', 'HEAD']); return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
} }
/** /**
@@ -164,7 +168,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
* *
* @return string datestamp of the latest notice in the stream * @return string datestamp of the latest notice in the stream
*/ */
public function lastModified() function lastModified()
{ {
return strtotime($this->notice->created); return strtotime($this->notice->created);
} }
@@ -177,7 +181,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
* *
* @return string etag * @return string etag
*/ */
public function etag() function etag()
{ {
return '"' . implode( return '"' . implode(
':', ':',
@@ -190,7 +194,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
. '"'; . '"';
} }
public function deleteNotice() function deleteNotice()
{ {
if ($this->format != 'atom') { if ($this->format != 'atom') {
// TRANS: Client error displayed when trying to delete a notice not using the Atom format. // TRANS: Client error displayed when trying to delete a notice not using the Atom format.
@@ -211,7 +215,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
// @fixme is there better output we could do here? // @fixme is there better output we could do here?
http_response_code(200); header('HTTP/1.1 200 OK');
header('Content-Type: text/plain'); header('Content-Type: text/plain');
// TRANS: Confirmation of notice deletion in API. %d is the ID (number) of the deleted notice. // TRANS: Confirmation of notice deletion in API. %d is the ID (number) of the deleted notice.
print(sprintf(_('Deleted notice %d'), $this->notice->id)); print(sprintf(_('Deleted notice %d'), $this->notice->id));

View File

@@ -35,7 +35,7 @@ if (!defined('STATUSNET')) {
exit(1); exit(1);
} }
require_once INSTALLDIR . '/lib/feeds/atomlistnoticefeed.php'; require_once INSTALLDIR . '/lib/atomlistnoticefeed.php';
/** /**
* Returns the most recent notices (default 20) posted to the list specified by ID * Returns the most recent notices (default 20) posted to the list specified by ID

View File

@@ -1,24 +1,26 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Show a user's timeline * Show a user's timeline
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Craig Andrews <candrews@integralblue.com> * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com> * @author Jeffery To <jeffery.to@gmail.com>
@@ -28,10 +30,13 @@
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc. * @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) {
exit(1);
}
/** /**
* Returns the most recent notices (default 20) posted by the authenticating * Returns the most recent notices (default 20) posted by the authenticating
@@ -39,7 +44,7 @@ defined('GNUSOCIAL') || die();
* is the API equivalent of the user profile web page. * is the API equivalent of the user profile web page.
* *
* @category API * @category API
* @package GNUsocial * @package StatusNet
* @author Craig Andrews <candrews@integralblue.com> * @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com> * @author Jeffery To <jeffery.to@gmail.com>
@@ -47,7 +52,8 @@ defined('GNUSOCIAL') || die();
* @author Mike Cochrane <mikec@mikenz.geek.nz> * @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info> * @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ApiTimelineUserAction extends ApiBareAuthAction class ApiTimelineUserAction extends ApiBareAuthAction
{ {
@@ -95,14 +101,16 @@ class ApiTimelineUserAction extends ApiBareAuthAction
if (!empty($this->notices) && (count($this->notices) > 0)) { if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1; $last = count($this->notices) - 1;
return '"' . implode(':', [ return '"' . implode(
$this->arg('action'), ':',
array($this->arg('action'),
common_user_cache_hash($this->scoped), common_user_cache_hash($this->scoped),
common_language(), common_language(),
$this->target->getID(), $this->target->getID(),
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created), strtotime($this->notices[$last]->created))
]) . '"'; )
. '"';
} }
return null; return null;
@@ -242,7 +250,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
} }
Event::handle('EndAtomPubNewActivity', array($activity, $this->target, $stored)); Event::handle('EndAtomPubNewActivity', array($activity, $this->target, $stored));
http_response_code(201); header('HTTP/1.1 201 Created');
header("Location: " . common_local_url('ApiStatusesShow', array('id' => $stored->getID(), header("Location: " . common_local_url('ApiStatusesShow', array('id' => $stored->getID(),
'format' => 'atom'))); 'format' => 'atom')));
$this->showSingleAtomStatus($stored); $this->showSingleAtomStatus($stored);

View File

@@ -1,42 +1,49 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social /**
// * StatusNet, the distributed open-source microblogging tool
// GNU social is free software: you can redistribute it and/or modify *
// it under the terms of the GNU Affero General Public License as published by * Show notice attachments
// the Free Software Foundation, either version 3 of the License, or *
// (at your option) any later version. * PHP version 5
// *
// GNU social is distributed in the hope that it will be useful, * LICENCE: This program is free software: you can redistribute it and/or modify
// but WITHOUT ANY WARRANTY; without even the implied warranty of * it under the terms of the GNU Affero General Public License as published by
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * the Free Software Foundation, either version 3 of the License, or
// GNU Affero General Public License for more details. * (at your option) any later version.
// *
// You should have received a copy of the GNU Affero General Public License * This program is distributed in the hope that it will be useful,
// along with GNU social. If not, see <http://www.gnu.org/licenses/>. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Personal
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2008-2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Show notice attachments * Show notice attachments
* *
* @category Personal * @category Personal
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @link http://status.net/
*/ */
class AttachmentAction extends ManagedAction class AttachmentAction extends ManagedAction
{ {
/** /**
* Attachment File object to show * Attachment File object to show
*/ */
public $attachment = null; var $attachment = null;
public $filehash = null;
public $filepath = null;
public $filesize = null;
public $mimetype = null;
public $filename = null;
/** /**
* Load attributes based on database arguments * Load attributes based on database arguments
@@ -45,52 +52,41 @@ class AttachmentAction extends ManagedAction
* *
* @param array $args $_REQUEST array * @param array $args $_REQUEST array
* *
* @return bool flag * @return success flag
* @throws ClientException
* @throws FileNotFoundException
* @throws FileNotStoredLocallyException
* @throws InvalidFilenameException
* @throws ServerException
*/ */
protected function prepare(array $args = [])
protected function prepare(array $args=array())
{ {
parent::prepare($args); parent::prepare($args);
try { try {
if (!empty($id = $this->trimmed('attachment'))) { if (!empty($id = $this->trimmed('attachment'))) {
$this->attachment = File::getByID((int) $id); $this->attachment = File::getByID($id);
} elseif (!empty($this->filehash = $this->trimmed('filehash'))) { } elseif (!empty($filehash = $this->trimmed('filehash'))) {
$file = File::getByHash($this->filehash); $this->attachment = File::getByHash($filehash);
$file->fetch();
$this->attachment = $file;
} }
} catch (Exception $e) { } catch (Exception $e) {
// Not found // Not found
} }
if (!$this->attachment instanceof File) { if (!$this->attachment instanceof File) {
// TRANS: Client error displayed trying to get a non-existing attachment. // TRANS: Client error displayed trying to get a non-existing attachment.
$this->clientError(_m('No such attachment.'), 404); $this->clientError(_('No such attachment.'), 404);
} }
$this->filesize = $this->attachment->size; $filename = $this->attachment->getFileOrThumbnailPath();
$this->mimetype = $this->attachment->mimetype;
$this->filename = $this->attachment->filename;
if ($this->attachment->isLocal() || $this->attachment->isFetchedRemoteFile()) { if (empty($filename)) {
$this->filesize = $this->attachment->getFileOrThumbnailSize(); $this->clientError(_('Requested local URL for a file that is not stored locally.'), 404);
$this->mimetype = $this->attachment->getFileOrThumbnailMimetype();
$this->filename = MediaFile::getDisplayName($this->attachment);
} }
return true; return true;
} }
/** /**
* Is this action read-only? * Is this action read-only?
* *
* @return bool true * @return boolean true
*/ */
public function isReadOnly($args): bool function isReadOnly($args)
{ {
return true; return true;
} }
@@ -100,14 +96,19 @@ class AttachmentAction extends ManagedAction
* *
* @return string title of the page * @return string title of the page
*/ */
public function title(): string function title()
{ {
$a = new Attachment($this->attachment); $a = new Attachment($this->attachment);
return $a->title(); return $a->title();
} }
public function showPage(): void public function showPage()
{ {
if (empty($this->attachment->getFileOrThumbnailPath())) {
// if it's not a local file, gtfo
common_redirect($this->attachment->getUrl(), 303);
}
parent::showPage(); parent::showPage();
} }
@@ -118,10 +119,10 @@ class AttachmentAction extends ManagedAction
* *
* @return void * @return void
*/ */
public function showContent(): void function showContent()
{ {
$ali = new Attachment($this->attachment, $this); $ali = new Attachment($this->attachment, $this);
$ali->show(); $cnt = $ali->show();
} }
/** /**
@@ -129,7 +130,7 @@ class AttachmentAction extends ManagedAction
* *
* @return void * @return void
*/ */
public function showPageNoticeBlock(): void function showPageNoticeBlock()
{ {
} }
@@ -138,8 +139,7 @@ class AttachmentAction extends ManagedAction
* *
* @return void * @return void
*/ */
public function showSections(): void function showSections() {
{
$ns = new AttachmentNoticeSection($this); $ns = new AttachmentNoticeSection($this);
$ns->show(); $ns->show();
} }
@@ -148,14 +148,13 @@ class AttachmentAction extends ManagedAction
* Last-modified date for file * Last-modified date for file
* *
* @return int last-modified date as unix timestamp * @return int last-modified date as unix timestamp
* @throws ServerException
*/ */
public function lastModified(): ?int public function lastModified()
{ {
if (common_config('site', 'use_x_sendfile')) { if (common_config('site', 'use_x_sendfile')) {
return null; return null;
} }
$path = $this->filepath; $path = $this->attachment->getFileOrThumbnailPath();
if (!empty($path)) { if (!empty($path)) {
return filemtime($path); return filemtime($path);
} else { } else {
@@ -170,26 +169,26 @@ class AttachmentAction extends ManagedAction
* but in decimal instead of hex. * but in decimal instead of hex.
* *
* @return string etag http header * @return string etag http header
* @throws ServerException
*/ */
public function etag(): ?string function etag()
{ {
if (common_config('site', 'use_x_sendfile')) { if (common_config('site', 'use_x_sendfile')) {
return null; return null;
} }
$path = $this->filepath; $path = $this->attachment->getFileOrThumbnailPath();
$cache = Cache::instance(); $cache = Cache::instance();
if ($cache) { if($cache) {
if (empty($path)) { if (empty($path)) {
return null; return null;
} }
$key = Cache::key('attachments:etag:' . $path); $key = Cache::key('attachments:etag:' . $path);
$etag = $cache->get($key); $etag = $cache->get($key);
if ($etag === false) { if($etag === false) {
$etag = crc32(file_get_contents($path)); $etag = crc32(file_get_contents($path));
$cache->set($key, $etag); $cache->set($key,$etag);
} }
return $etag; return $etag;
} }
@@ -201,4 +200,36 @@ class AttachmentAction extends ManagedAction
return null; return null;
} }
} }
/**
* Include $filepath in the response, for viewing and downloading.
* If provided, $filesize is used to size the HTTP request,
* otherwise it's value is calculated
* @param string $filepath the absolute path to the file to send
* @param $filesize optional, calculated if unkown
*/
static function sendFile(string $filepath, $filesize) {
if (is_string(common_config('site', 'x-static-delivery'))) {
$tmp = explode(INSTALLDIR, $filepath);
$relative_path = end($tmp);
common_debug("Using Static Delivery with header: '" .
common_config('site', 'x-static-delivery') . ": {$relative_path}'");
header(common_config('site', 'x-static-delivery') . ": {$relative_path}");
} else {
if (empty($filesize)) {
$filesize = filesize($filepath);
}
header("Content-Length: {$filesize}");
// header('Cache-Control: private, no-transform, no-store, must-revalidate');
$ret = @readfile($filepath);
if ($ret === false) {
common_log(LOG_ERR, "Couldn't read file at {$filepath}.");
} elseif ($ret !== $filesize) {
common_log(LOG_ERR, "The lengths of the file as recorded on the DB (or on disk) for the file " .
"{$filepath} differ from what was sent to the user ({$filesize} vs {$ret}).");
}
}
}
} }

View File

@@ -1,20 +1,6 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Download notice attachment * Download notice attachment
@@ -22,35 +8,35 @@ defined('GNUSOCIAL') || die();
* @category Personal * @category Personal
* @package GNUsocial * @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se> * @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2016 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or late * @link https:/gnu.io/social
*/ */
class Attachment_downloadAction extends AttachmentAction class Attachment_downloadAction extends AttachmentAction
{ {
public function showPage(): void public function showPage()
{ {
// Checks file exists or throws FileNotFoundException
$filepath = $this->attachment->getFileOrThumbnailPath();
$filesize = $this->attachment->getFileOrThumbnailSize();
$mimetype = $this->attachment->getFileOrThumbnailMimetype();
if (empty($filepath)) {
$this->clientError(_('No such attachment'), 404);
}
$filename = MediaFile::getDisplayName($this->attachment);
// Disable errors, to not mess with the file contents (suppress errors in case access to this // Disable errors, to not mess with the file contents (suppress errors in case access to this
// function is blocked, like in some shared hosts). Automatically reset at the end of the // function is blocked, like in some shared hosts). Automatically reset at the end of the
// script execution, and we don't want to have any more errors until then, so don't reset it // script execution, and we don't want to have any more errors until then, so don't reset it
@ini_set('display_errors', 0); @ini_set('display_errors', 0);
if ($this->attachment->isLocal()) { header("Content-Description: File Transfer");
try { header("Content-Type: {$mimetype}");
$this->filepath = $this->attachment->getFileOrThumbnailPath(); header("Content-Disposition: attachment; filename=\"{$filename}\"");
} catch (Exception $e) { header('Expires: 0');
$this->clientError( header('Content-Transfer-Encoding: binary'); // FIXME? Can this be different?
_m('Requested local URL for a file that is not stored locally.'),
404 AttachmentAction::sendFile($filepath, $filesize);
);
}
common_send_file(
$this->filepath,
$this->mimetype,
$this->filename,
'attachment'
);
} else {
common_redirect($this->attachment->getUrl(), 303);
}
} }
} }

View File

@@ -1,31 +1,44 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social /**
// * StatusNet, the distributed open-source microblogging tool
// GNU social is free software: you can redistribute it and/or modify *
// it under the terms of the GNU Affero General Public License as published by * Show notice attachments
// the Free Software Foundation, either version 3 of the License, or *
// (at your option) any later version. * PHP version 5
// *
// GNU social is distributed in the hope that it will be useful, * LICENCE: This program is free software: you can redistribute it and/or modify
// but WITHOUT ANY WARRANTY; without even the implied warranty of * it under the terms of the GNU Affero General Public License as published by
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * the Free Software Foundation, either version 3 of the License, or
// GNU Affero General Public License for more details. * (at your option) any later version.
// *
// You should have received a copy of the GNU Affero General Public License * This program is distributed in the hope that it will be useful,
// along with GNU social. If not, see <http://www.gnu.org/licenses/>. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Personal
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2008-2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Show notice attachments * Show notice attachments
* *
* @category Personal * @category Personal
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @link http://status.net/
*/ */
class Attachment_thumbnailAction extends Attachment_viewAction class Attachment_thumbnailAction extends AttachmentAction
{ {
protected $thumb_w = null; // max width protected $thumb_w = null; // max width
protected $thumb_h = null; // max height protected $thumb_h = null; // max height
@@ -45,35 +58,38 @@ class Attachment_thumbnailAction extends Attachment_viewAction
* requested in the GET variables (read in the constructor). Tries * requested in the GET variables (read in the constructor). Tries
* to send the most appropriate file with the correct size and * to send the most appropriate file with the correct size and
* headers or displays an error if it's not possible. * headers or displays an error if it's not possible.
* @throws ClientException
* @throws ReflectionException
* @throws ServerException
*/ */
public function showPage(): void public function showPage()
{ {
// Returns a File_thumbnail object or throws exception if not available // Returns a File_thumbnail object or throws exception if not available
$filename = $this->filename;
$filepath = $this->filepath;
try { try {
$thumbnail = $this->attachment->getThumbnail($this->thumb_w, $this->thumb_h, $this->thumb_c); $thumbnail = $this->attachment->getThumbnail($this->thumb_w, $this->thumb_h, $this->thumb_c);
$filename = $thumbnail->getFilename(); $file = $thumbnail->getFile();
$filepath = $thumbnail->getPath();
} catch (UseFileAsThumbnailException $e) { } catch (UseFileAsThumbnailException $e) {
// With this exception, the file exists locally $e->file; // With this exception, the file exists locally
} catch (FileNotFoundException $e) { $file = $e->file;
$this->clientError(_m('No such attachment'), 404); } catch(FileNotFoundException $e) {
} catch (Exception $e) { $this->clientError(_('No such attachment'), 404);
if (is_null($filepath)) {
$this->clientError(_m('No such thumbnail'), 404);
}
// Remote file
} }
// Checks file exists or throws FileNotFoundException
$filepath = $file->getFileOrThumbnailPath($thumbnail);
$filesize = $this->attachment->getFileOrThumbnailSize($thumbnail);
$mimetype = $file->getFileOrThumbnailMimetype($thumbnail);
$filename = MediaFile::getDisplayName($file);
// Disable errors, to not mess with the file contents (suppress errors in case access to this // Disable errors, to not mess with the file contents (suppress errors in case access to this
// function is blocked, like in some shared hosts). Automatically reset at the end of the // function is blocked, like in some shared hosts). Automatically reset at the end of the
// script execution, and we don't want to have any more errors until then, so don't reset it // script execution, and we don't want to have any more errors until then, so don't reset it
@ini_set('display_errors', 0); @ini_set('display_errors', 0);
common_send_file($filepath, image_type_to_mime_type(IMAGETYPE_WEBP), $filename, 'inline'); header("Content-Description: File Transfer");
header("Content-Type: {$mimetype}");
header("Content-Disposition: inline; filename=\"{$filename}\"");
header('Expires: 0');
header('Content-Transfer-Encoding: binary');
AttachmentAction::sendFile($filepath, $filesize);
} }
} }

View File

@@ -1,54 +1,44 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* View notice attachment * View notice attachment
* *
* @package GNUsocial * @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se> * @author Miguel Dantas <biodantasgs@gmail.com>
* @copyright 2016 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/ */
class Attachment_viewAction extends AttachmentAction class Attachment_viewAction extends AttachmentAction
{ {
public function showPage(): void public function showPage()
{ {
// Checks file exists or throws FileNotFoundException
$filepath = $this->attachment->getFileOrThumbnailPath();
$filesize = $this->attachment->getFileOrThumbnailSize();
$mimetype = $this->attachment->getFileOrThumbnailMimetype();
if (empty($filepath)) {
$this->clientError(_('No such attachment'), 404);
}
$filename = MediaFile::getDisplayName($this->attachment);
// Disable errors, to not mess with the file contents (suppress errors in case access to this // Disable errors, to not mess with the file contents (suppress errors in case access to this
// function is blocked, like in some shared hosts). Automatically reset at the end of the // function is blocked, like in some shared hosts). Automatically reset at the end of the
// script execution, and we don't want to have any more errors until then, so don't reset it // script execution, and we don't want to have any more errors until then, so don't reset it
@ini_set('display_errors', 0); @ini_set('display_errors', 0);
if ($this->attachment->isLocal() || $this->attachment->isFetchedRemoteFile()) { header("Content-Description: File Transfer");
try { header("Content-Type: {$mimetype}");
$this->filepath = $this->attachment->getFileOrThumbnailPath(); if (in_array(common_get_mime_media($mimetype), ['image', 'video'])) {
} catch (Exception $e) { header("Content-Disposition: inline; filename=\"{$filename}\"");
$this->clientError(
_m('Requested local URL for a file that is not stored locally.'),
404
);
}
$disposition = 'attachment';
if (in_array(common_get_mime_media($this->mimetype), ['image', 'video'])) {
$disposition = 'inline';
}
common_send_file($this->filepath, $this->mimetype, $this->filename, $disposition);
} else { } else {
common_redirect($this->attachment->getUrl(), 303); header("Content-Disposition: attachment; filename=\"{$filename}\"");
} }
header('Expires: 0');
header('Content-Transfer-Encoding: binary');
AttachmentAction::sendFile($filepath, $filesize);
} }
} }

View File

@@ -1,67 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Retrieve user avatar by filename action class.
*
* @category Action
* @package GNUsocial
*
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
*/
defined('GNUSOCIAL') || die;
/**
* Retrieve user avatar by filename action class.
*
* @category Action
* @package GNUsocial
*
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @author Mikael Nordfeldth <mmn@hethane.se>
* @author Hugo Sales <hugo@fc.up.pt>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
*
* @see http://www.gnu.org/software/social/
*/
class AvatarAction extends Action
{
public $filename = null;
public $filepath = null;
public $mimetype = null;
protected function prepare(array $args = [])
{
parent::prepare($args);
$this->filename = File::tryFilename($this->trimmed('file'));
$this->filepath = File::path($this->filename, common_config('avatar', 'dir'), false);
if (!file_exists($this->filepath)) {
// TRANS: Client error displayed trying to get a non-existing avatar.
$this->clientError(_m('No such avatar.'), 404);
}
$this->mimetype = (new ImageFile(-1, $this->filepath))->mimetype;
return true;
}
protected function handle()
{
parent::handle();
common_send_file($this->filepath, $this->mimetype, $this->filename, 'inline');
}
}

View File

@@ -1,32 +1,34 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Upload an avatar * Upload an avatar
* *
* @category Settings * PHP version 5
* @package GNUsocial
* *
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @author Diogo Cordeiro <diogo@fc.up.pt> * @copyright 2008-2009 StatusNet, Inc.
* @copyright 2008-2009, 2020 Free Software Foundation http://fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die;
if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Upload an avatar * Upload an avatar
@@ -35,26 +37,24 @@ defined('GNUSOCIAL') || die;
* *
* @category Settings * @category Settings
* @package StatusNet * @package StatusNet
*
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @author Sarven Capadisli <csarven@status.net> * @author Sarven Capadisli <csarven@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* * @link http://status.net/
* @see http://status.net/
*/ */
class AvatarsettingsAction extends SettingsAction class AvatarsettingsAction extends SettingsAction
{ {
public $mode; var $mode = null;
public $imagefile; var $imagefile = null;
public $filename; var $filename = null;
public function prepare(array $args = []) function prepare(array $args=array())
{ {
$avatarpath = Avatar::path(''); $avatarpath = Avatar::path('');
if (!is_writable($avatarpath)) { if (!is_writable($avatarpath)) {
throw new Exception(_m("The administrator of your site needs to throw new Exception(_("The administrator of your site needs to
add write permissions on the avatar upload folder before add write permissions on the avatar upload folder before
you're able to set one.")); you're able to set one."));
} }
@@ -67,30 +67,24 @@ class AvatarsettingsAction extends SettingsAction
* Title of the page * Title of the page
* *
* @return string Title of the page * @return string Title of the page
* @throws Exception
*
*/ */
public function title() function title()
{ {
// TRANS: Title for avatar upload page. // TRANS: Title for avatar upload page.
return _m('Avatar'); return _('Avatar');
} }
/** /**
* Instructions for use * Instructions for use
* *
* @return string instructions for use * @return instructions for use
* @throws Exception
*
*/ */
public function getInstructions() function getInstructions()
{ {
// TRANS: Instruction for avatar upload page. // TRANS: Instruction for avatar upload page.
// TRANS: %s is the maximum file size, for example "500b", "10kB" or "2MB". // TRANS: %s is the maximum file size, for example "500b", "10kB" or "2MB".
return sprintf( return sprintf(_('You can upload your personal avatar. The maximum file size is %s.'),
_m('You can upload your personal avatar. The maximum file size is %s.'), ImageFile::maxFileSize());
ImageFile::maxFileSize()
);
} }
/** /**
@@ -101,7 +95,7 @@ class AvatarsettingsAction extends SettingsAction
* *
* @return void * @return void
*/ */
public function showContent() function showContent()
{ {
if ($this->mode == 'crop') { if ($this->mode == 'crop') {
$this->showCropForm(); $this->showCropForm();
@@ -110,37 +104,33 @@ class AvatarsettingsAction extends SettingsAction
} }
} }
public function showUploadForm() function showUploadForm()
{ {
// If we detect that the user didn't finish setting a new avatar, remove the temporary file. $this->elementStart('form', array('enctype' => 'multipart/form-data',
if (isset($_SESSION['FILEDATA'])) {
@unlink($_SESSION['FILEDATA']['filepath']);
unset($_SESSION['FILEDATA']);
}
$this->elementStart('form', ['enctype' => 'multipart/form-data',
'method' => 'post', 'method' => 'post',
'id' => 'form_settings_avatar', 'id' => 'form_settings_avatar',
'class' => 'form_settings', 'class' => 'form_settings',
'action' => common_local_url('avatarsettings'),]); 'action' =>
common_local_url('avatarsettings')));
$this->elementStart('fieldset'); $this->elementStart('fieldset');
// TRANS: Avatar upload page form legend. // TRANS: Avatar upload page form legend.
$this->element('legend', null, _m('Avatar settings')); $this->element('legend', null, _('Avatar settings'));
$this->hidden('token', common_session_token()); $this->hidden('token', common_session_token());
if (Event::handle('StartAvatarFormData', [$this])) { if (Event::handle('StartAvatarFormData', array($this))) {
$this->elementStart('ul', 'form_data'); $this->elementStart('ul', 'form_data');
try { try {
$original = Avatar::getUploaded($this->scoped); $original = Avatar::getUploaded($this->scoped);
$this->elementStart('li', ['id' => 'avatar_original', $this->elementStart('li', array('id' => 'avatar_original',
'class' => 'avatar_view',]); 'class' => 'avatar_view'));
// TRANS: Header on avatar upload page for thumbnail of originally uploaded avatar (h2). // TRANS: Header on avatar upload page for thumbnail of originally uploaded avatar (h2).
$this->element('h2', null, _m('Original')); $this->element('h2', null, _("Original"));
$this->elementStart('div', ['id' => 'avatar_original_view']); $this->elementStart('div', array('id'=>'avatar_original_view'));
$this->element('img', ['src' => $original->displayUrl(), $this->element('img', array('src' => $original->displayUrl(),
'width' => $original->width, 'width' => $original->width,
'height' => $original->height, 'height' => $original->height,
'alt' => $this->scoped->getNickname(),]); 'alt' => $this->scoped->getNickname()));
$this->elementEnd('div'); $this->elementEnd('div');
$this->elementEnd('li'); $this->elementEnd('li');
} catch (NoAvatarException $e) { } catch (NoAvatarException $e) {
@@ -149,100 +139,97 @@ class AvatarsettingsAction extends SettingsAction
try { try {
$avatar = $this->scoped->getAvatar(AVATAR_PROFILE_SIZE); $avatar = $this->scoped->getAvatar(AVATAR_PROFILE_SIZE);
$this->elementStart('li', ['id' => 'avatar_preview', $this->elementStart('li', array('id' => 'avatar_preview',
'class' => 'avatar_view',]); 'class' => 'avatar_view'));
// TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2). // TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2).
$this->element('h2', null, _m('Preview')); $this->element('h2', null, _("Preview"));
$this->elementStart('div', ['id' => 'avatar_preview_view']); $this->elementStart('div', array('id'=>'avatar_preview_view'));
$this->element('img', ['src' => $avatar->displayUrl(), $this->element('img', array('src' => $avatar->displayUrl(),
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
'alt' => $this->scoped->getNickname(),]); 'alt' => $this->scoped->getNickname()));
$this->elementEnd('div'); $this->elementEnd('div');
if (!empty($avatar->filename)) { if (!empty($avatar->filename)) {
// TRANS: Button on avatar upload page to delete current avatar. // TRANS: Button on avatar upload page to delete current avatar.
$this->submit('delete', _m('BUTTON', 'Delete')); $this->submit('delete', _m('BUTTON','Delete'));
} }
$this->elementEnd('li'); $this->elementEnd('li');
} catch (NoAvatarException $e) { } catch (NoAvatarException $e) {
// No previously uploaded avatar to preview. // No previously uploaded avatar to preview.
} }
$this->elementStart('li', ['id' => 'settings_attach']); $this->elementStart('li', array ('id' => 'settings_attach'));
$this->element('input', ['name' => 'MAX_FILE_SIZE', $this->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden', 'type' => 'hidden',
'id' => 'MAX_FILE_SIZE', 'id' => 'MAX_FILE_SIZE',
'value' => ImageFile::maxFileSizeInt(),]); 'value' => ImageFile::maxFileSizeInt()));
$this->element('input', ['name' => 'avatarfile', $this->element('input', array('name' => 'avatarfile',
'type' => 'file', 'type' => 'file',
'id' => 'avatarfile',]); 'id' => 'avatarfile'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
$this->elementStart('ul', 'form_actions'); $this->elementStart('ul', 'form_actions');
$this->elementStart('li'); $this->elementStart('li');
// TRANS: Button on avatar upload page to upload an avatar. // TRANS: Button on avatar upload page to upload an avatar.
$this->submit('upload', _m('BUTTON', 'Upload')); $this->submit('upload', _m('BUTTON','Upload'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
} }
Event::handle('EndAvatarFormData', [$this]); Event::handle('EndAvatarFormData', array($this));
$this->elementEnd('fieldset'); $this->elementEnd('fieldset');
$this->elementEnd('form'); $this->elementEnd('form');
} }
public function showCropForm() function showCropForm()
{ {
$this->elementStart('form', ['method' => 'post', $this->elementStart('form', array('method' => 'post',
'id' => 'form_settings_avatar', 'id' => 'form_settings_avatar',
'class' => 'form_settings', 'class' => 'form_settings',
'action' => common_local_url('avatarsettings'),]); 'action' =>
common_local_url('avatarsettings')));
$this->elementStart('fieldset'); $this->elementStart('fieldset');
// TRANS: Avatar upload page crop form legend. // TRANS: Avatar upload page crop form legend.
$this->element('legend', null, _m('Avatar settings')); $this->element('legend', null, _('Avatar settings'));
$this->hidden('token', common_session_token()); $this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data'); $this->elementStart('ul', 'form_data');
$this->elementStart( $this->elementStart('li',
'li', array('id' => 'avatar_original',
['id' => 'avatar_original', 'class' => 'avatar_view'));
'class' => 'avatar_view',]
);
// TRANS: Header on avatar upload crop form for thumbnail of originally uploaded avatar (h2). // TRANS: Header on avatar upload crop form for thumbnail of originally uploaded avatar (h2).
$this->element('h2', null, _m('Original')); $this->element('h2', null, _('Original'));
$this->elementStart('div', ['id' => 'avatar_original_view']); $this->elementStart('div', array('id'=>'avatar_original_view'));
$this->element('img', ['src' => Avatar::url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => $this->filedata['width'], 'width' => $this->filedata['width'],
'height' => $this->filedata['height'], 'height' => $this->filedata['height'],
'alt' => $this->scoped->getNickname(),]); 'alt' => $this->scoped->getNickname()));
$this->elementEnd('div'); $this->elementEnd('div');
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementStart( $this->elementStart('li',
'li', array('id' => 'avatar_preview',
['id' => 'avatar_preview', 'class' => 'avatar_view'));
'class' => 'avatar_view',]
);
// TRANS: Header on avatar upload crop form for thumbnail of to be used rendition of uploaded avatar (h2). // TRANS: Header on avatar upload crop form for thumbnail of to be used rendition of uploaded avatar (h2).
$this->element('h2', null, _m('Preview')); $this->element('h2', null, _('Preview'));
$this->elementStart('div', ['id' => 'avatar_preview_view']); $this->elementStart('div', array('id'=>'avatar_preview_view'));
$this->element('img', ['src' => Avatar::url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
'alt' => $this->scoped->getNickname(),]); 'alt' => $this->scoped->getNickname()));
$this->elementEnd('div'); $this->elementEnd('div');
foreach (['avatar_crop_x', 'avatar_crop_y', foreach (array('avatar_crop_x', 'avatar_crop_y',
'avatar_crop_w', 'avatar_crop_h',] as $crop_info) { 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
$this->element('input', ['name' => $crop_info, $this->element('input', array('name' => $crop_info,
'type' => 'hidden', 'type' => 'hidden',
'id' => $crop_info,]); 'id' => $crop_info));
} }
// TRANS: Button on avatar upload crop form to confirm a selected crop as avatar. // TRANS: Button on avatar upload crop form to confirm a selected crop as avatar.
$this->submit('crop', _m('BUTTON', 'Crop')); $this->submit('crop', _m('BUTTON','Crop'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
@@ -250,31 +237,20 @@ class AvatarsettingsAction extends SettingsAction
$this->elementEnd('form'); $this->elementEnd('form');
} }
/**
* @return string
* @throws NoResultException
* @throws NoUploadedMediaException
* @throws ServerException
* @throws UnsupportedMediaException
* @throws UseFileAsThumbnailException
* @throws Exception
*
* @throws ClientException
*/
protected function doPost() protected function doPost()
{ {
if (Event::handle('StartAvatarSaveForm', [$this])) { if (Event::handle('StartAvatarSaveForm', array($this))) {
if ($this->trimmed('upload')) { if ($this->trimmed('upload')) {
return $this->uploadAvatar(); return $this->uploadAvatar();
} elseif ($this->trimmed('crop')) { } else if ($this->trimmed('crop')) {
return $this->cropAvatar(); return $this->cropAvatar();
} elseif ($this->trimmed('delete')) { } else if ($this->trimmed('delete')) {
return $this->deleteAvatar(); return $this->deleteAvatar();
} else { } else {
// TRANS: Unexpected validation error on avatar upload form. // TRANS: Unexpected validation error on avatar upload form.
throw new ClientException(_m('Unexpected form submission.')); throw new ClientException(_('Unexpected form submission.'));
} }
Event::handle('EndAvatarSaveForm', [$this]); Event::handle('EndAvatarSaveForm', array($this));
} }
} }
@@ -284,39 +260,28 @@ class AvatarsettingsAction extends SettingsAction
* Does all the magic for handling an image upload, and crops the * Does all the magic for handling an image upload, and crops the
* image by default. * image by default.
* *
* @return string * @return void
* @throws NoResultException
* @throws NoUploadedMediaException
* @throws ServerException
* @throws UnsupportedMediaException
* @throws UseFileAsThumbnailException
*
* @throws ClientException
*/ */
public function uploadAvatar(): string function uploadAvatar()
{ {
// ImageFile throws exception if something goes wrong, which we'll // ImageFile throws exception if something goes wrong, which we'll
// pick up and show as an error message above the form. // pick up and show as an error message above the form.
$imagefile = ImageFile::fromUpload('avatarfile'); $imagefile = ImageFile::fromUpload('avatarfile');
$type = $imagefile->preferredType(); $type = $imagefile->preferredType();
$filename = Avatar::filename( $filename = Avatar::filename($this->scoped->getID(),
$this->scoped->getID(),
image_type_to_extension($type), image_type_to_extension($type),
null, null,
'tmp' . common_timestamp() 'tmp'.common_timestamp());
);
$filepath = Avatar::path($filename); $filepath = Avatar::path($filename);
$imagefile = $imagefile->copyTo($filepath); $imagefile = $imagefile->copyTo($filepath);
$filedata = [ $filedata = array('filename' => $filename,
'filename' => $filename,
'filepath' => $filepath, 'filepath' => $filepath,
'width' => $imagefile->width, 'width' => $imagefile->width,
'height' => $imagefile->height, 'height' => $imagefile->height,
'type' => $type, 'type' => $type);
];
$_SESSION['FILEDATA'] = $filedata; $_SESSION['FILEDATA'] = $filedata;
@@ -325,18 +290,13 @@ class AvatarsettingsAction extends SettingsAction
$this->mode = 'crop'; $this->mode = 'crop';
// TRANS: Avatar upload form instruction after uploading a file. // TRANS: Avatar upload form instruction after uploading a file.
return _m('Pick a square area of the image to be your avatar.'); return _('Pick a square area of the image to be your avatar.');
} }
/** /**
* Handle the results of jcrop. * Handle the results of jcrop.
* *
* @return string * @return void
* @throws NoResultException
* @throws ServerException
* @throws UnsupportedMediaException
*
* @throws ClientException
*/ */
public function cropAvatar() public function cropAvatar()
{ {
@@ -344,34 +304,30 @@ class AvatarsettingsAction extends SettingsAction
if (empty($filedata)) { if (empty($filedata)) {
// TRANS: Server error displayed if an avatar upload went wrong somehow server side. // TRANS: Server error displayed if an avatar upload went wrong somehow server side.
throw new ServerException(_m('Lost our file data.')); throw new ServerException(_('Lost our file data.'));
} }
$file_d = min($filedata['width'], $filedata['height']); $file_d = min($filedata['width'], $filedata['height']);
$dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x') : 0; $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
$dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y') : 0; $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
$dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w') : $file_d; $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w'):$file_d;
$dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h') : $file_d; $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h'):$file_d;
$size = (int)(min($dest_w, $dest_h, common_config('avatar', 'maxsize'))); $size = intval(min($dest_w, $dest_h, common_config('avatar', 'maxsize')));
$box = ['width' => $size, 'height' => $size, $box = array('width' => $size, 'height' => $size,
'x' => $dest_x, 'y' => $dest_y, 'x' => $dest_x, 'y' => $dest_y,
'w' => $dest_w, 'h' => $dest_h,]; 'w' => $dest_w, 'h' => $dest_h);
$imagefile = new ImageFile(-1, $filedata['filepath']); $imagefile = new ImageFile(null, $filedata['filepath']);
$filename = Avatar::filename( $filename = Avatar::filename($this->scoped->getID(), image_type_to_extension($imagefile->preferredType()),
$this->scoped->getID(), $size, common_timestamp());
image_type_to_extension($imagefile->preferredType()),
$size,
common_timestamp()
);
try { try {
$imagefile->resizeTo(Avatar::path($filename), $box); $imagefile->resizeTo(Avatar::path($filename), $box);
} catch (UseFileAsThumbnailException $e) { } catch (UseFileAsThumbnailException $e) {
common_debug('Using uploaded avatar directly without resizing, copying it to: ' . $filename); common_debug('Using uploaded avatar directly without resizing, copying it to: '.$filename);
if (!copy($filedata['filepath'], Avatar::path($filename))) { if (!copy($filedata['filepath'], Avatar::path($filename))) {
common_debug('Tried to copy image file ' . $filedata['filepath'] . ' to destination ' . Avatar::path($filename)); common_debug('Tried to copy image file '.$filedata['filepath'].' to destination '.Avatar::path($filename));
throw new ServerException('Could not copy file to destination.'); throw new ServerException('Could not copy file to destination.');
} }
} }
@@ -381,26 +337,24 @@ class AvatarsettingsAction extends SettingsAction
unset($_SESSION['FILEDATA']); unset($_SESSION['FILEDATA']);
$this->mode = 'upload'; $this->mode = 'upload';
// TRANS: Success message for having updated a user avatar. // TRANS: Success message for having updated a user avatar.
return _m('Avatar updated.'); return _('Avatar updated.');
} }
// TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason. // TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
throw new ServerException(_m('Failed updating avatar.')); throw new ServerException(_('Failed updating avatar.'));
} }
/** /**
* Get rid of the current avatar. * Get rid of the current avatar.
* *
* @return string * @return void
* @throws Exception
*
*/ */
public function deleteAvatar() function deleteAvatar()
{ {
Avatar::deleteFromProfile($this->scoped); Avatar::deleteFromProfile($this->scoped);
// TRANS: Success message for deleting a user avatar. // TRANS: Success message for deleting a user avatar.
return _m('Avatar deleted.'); return _('Avatar deleted.');
} }
/** /**
@@ -408,10 +362,11 @@ class AvatarsettingsAction extends SettingsAction
* *
* @return void * @return void
*/ */
public function showStylesheets()
function showStylesheets()
{ {
parent::showStylesheets(); parent::showStylesheets();
$this->cssLink('js/extlib/jquery-jcrop/css/jcrop.css', 'base', 'screen, projection, tv'); $this->cssLink('js/extlib/jquery-jcrop/css/jcrop.css','base','screen, projection, tv');
} }
/** /**
@@ -419,7 +374,7 @@ class AvatarsettingsAction extends SettingsAction
* *
* @return void * @return void
*/ */
public function showScripts() function showScripts()
{ {
parent::showScripts(); parent::showScripts();

View File

@@ -1,44 +1,50 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* Block a user action class. * Block a user action class.
* *
* PHP version 5
*
* @category Action * @category Action
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net> * @author Robin Millette <millette@status.net>
* @copyright 2008, 2009 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
defined('GNUSOCIAL') || die(); if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/** /**
* Block a user action class. * Block a user action class.
* *
* @category Action * @category Action
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net> * @author Robin Millette <millette@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/ */
class BlockAction extends ProfileFormAction class BlockAction extends ProfileFormAction
{ {
public $profile = null; var $profile = null;
/** /**
* Take arguments for running * Take arguments for running
@@ -47,7 +53,7 @@ class BlockAction extends ProfileFormAction
* *
* @return boolean success flag * @return boolean success flag
*/ */
public function prepare(array $args = []): bool function prepare(array $args = array())
{ {
if (!parent::prepare($args)) { if (!parent::prepare($args)) {
return false; return false;
@@ -72,7 +78,7 @@ class BlockAction extends ProfileFormAction
* *
* @return void * @return void
*/ */
public function handle(): void function handle()
{ {
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) { if ($this->arg('no')) {
@@ -88,19 +94,16 @@ class BlockAction extends ProfileFormAction
} }
} }
public function showContent(): void function showContent() {
{
$this->areYouSureForm(); $this->areYouSureForm();
} }
public function title(): string function title() {
{
// TRANS: Title for block user page. // TRANS: Title for block user page.
return _('Block user'); return _('Block user');
} }
public function showNoticeForm(): void function showNoticeForm() {
{
// nop // nop
} }
@@ -111,7 +114,7 @@ class BlockAction extends ProfileFormAction
* *
* @return void * @return void
*/ */
public function areYouSureForm() function areYouSureForm()
{ {
// @fixme if we ajaxify the confirmation form, skip the preview on ajax hits // @fixme if we ajaxify the confirmation form, skip the preview on ajax hits
$profile = new ArrayWrapper(array($this->profile)); $profile = new ArrayWrapper(array($this->profile));
@@ -128,44 +131,35 @@ class BlockAction extends ProfileFormAction
$this->hidden('token', common_session_token()); $this->hidden('token', common_session_token());
// TRANS: Legend for block user form. // TRANS: Legend for block user form.
$this->element('legend', _('Block user')); $this->element('legend', _('Block user'));
$this->element( $this->element('p', null,
'p',
null,
// TRANS: Explanation of consequences when blocking a user on the block user page. // TRANS: Explanation of consequences when blocking a user on the block user page.
_('Are you sure you want to block this user? ' _('Are you sure you want to block this user? '.
. 'Afterwards, they will be unsubscribed from you, ' 'Afterwards, they will be unsubscribed from you, '.
. 'unable to subscribe to you in the future, and ' 'unable to subscribe to you in the future, and '.
. 'you will not be notified of any @-replies from them.') 'you will not be notified of any @-replies from them.'));
); $this->element('input', array('id' => 'blockto-' . $id,
$this->element('input', [
'id' => 'blockto-' . $id,
'name' => 'profileid', 'name' => 'profileid',
'type' => 'hidden', 'type' => 'hidden',
'value' => $id 'value' => $id));
]);
foreach ($this->args as $k => $v) { foreach ($this->args as $k => $v) {
if (substr($k, 0, 9) == 'returnto-') { if (substr($k, 0, 9) == 'returnto-') {
$this->hidden($k, $v); $this->hidden($k, $v);
} }
} }
$this->submit( $this->submit('form_action-no',
'form_action-no',
// TRANS: Button label on the user block form. // TRANS: Button label on the user block form.
_m('BUTTON', 'No'), _m('BUTTON','No'),
'submit form_action-primary', 'submit form_action-primary',
'no', 'no',
// TRANS: Submit button title for 'No' when blocking a user. // TRANS: Submit button title for 'No' when blocking a user.
_('Do not block this user.') _('Do not block this user.'));
); $this->submit('form_action-yes',
$this->submit(
'form_action-yes',
// TRANS: Button label on the user block form. // TRANS: Button label on the user block form.
_m('BUTTON', 'Yes'), _m('BUTTON','Yes'),
'submit form_action-secondary', 'submit form_action-secondary',
'yes', 'yes',
// TRANS: Submit button title for 'Yes' when blocking a user. // TRANS: Submit button title for 'Yes' when blocking a user.
_('Block this user.') _('Block this user.'));
);
$this->elementEnd('fieldset'); $this->elementEnd('fieldset');
$this->elementEnd('form'); $this->elementEnd('form');
} }
@@ -176,7 +170,7 @@ class BlockAction extends ProfileFormAction
* @return void * @return void
*/ */
public function handlePost(): void function handlePost()
{ {
$cur = common_current_user(); $cur = common_current_user();
@@ -193,7 +187,7 @@ class BlockAction extends ProfileFormAction
} }
} }
public function showScripts(): void function showScripts()
{ {
parent::showScripts(); parent::showScripts();
$this->autofocus('form_action-yes'); $this->autofocus('form_action-yes');
@@ -207,14 +201,13 @@ class BlockAction extends ProfileFormAction
* @throws ClientException if token is bad on POST request or if we have * @throws ClientException if token is bad on POST request or if we have
* confirmation parameters which could trigger something. * confirmation parameters which could trigger something.
*/ */
public function checkSessionToken(): void function checkSessionToken()
{ {
if ( if ($_SERVER['REQUEST_METHOD'] == 'POST' ||
$_SERVER['REQUEST_METHOD'] === 'POST' $this->arg('yes') ||
|| $this->arg('yes') $this->arg('no')) {
|| $this->arg('no')
) { return parent::checkSessionToken();
parent::checkSessionToken();
} }
} }
@@ -224,14 +217,12 @@ class BlockAction extends ProfileFormAction
* *
* @return string URL * @return string URL
*/ */
public function defaultReturnTo() function defaultReturnTo()
{ {
$user = common_current_user(); $user = common_current_user();
if ($user) { if ($user) {
return common_local_url( return common_local_url('subscribers',
'subscribers', array('nickname' => $user->nickname));
['nickname' => $user->nickname]
);
} else { } else {
return common_local_url('public'); return common_local_url('public');
} }

View File

@@ -1,30 +1,33 @@
<?php <?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/** /**
* StatusNet, the distributed open-source microblogging tool
*
* Confirm an address * Confirm an address
* *
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Confirm * @category Confirm
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @copyright 2008-2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
defined('GNUSOCIAL') || die(); if (!defined('GNUSOCIAL')) { exit(1); }
/** /**
* Confirm an address * Confirm an address
@@ -34,9 +37,10 @@ defined('GNUSOCIAL') || die();
* accepts those codes. * accepts those codes.
* *
* @category Confirm * @category Confirm
* @package GNUsocial * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
class ConfirmaddressAction extends ManagedAction class ConfirmaddressAction extends ManagedAction
{ {
@@ -84,7 +88,7 @@ class ConfirmaddressAction extends ManagedAction
$cur = $this->scoped->getUser(); $cur = $this->scoped->getUser();
$cur->query('START TRANSACTION'); $cur->query('BEGIN');
if (in_array($type, array('email', 'sms'))) { if (in_array($type, array('email', 'sms'))) {
common_debug("Confirming {$type} address for user {$this->scoped->getID()}"); common_debug("Confirming {$type} address for user {$this->scoped->getID()}");
if ($cur->$type == $confirm->address) { if ($cur->$type == $confirm->address) {
@@ -110,12 +114,14 @@ class ConfirmaddressAction extends ManagedAction
if ($type == 'email') { if ($type == 'email') {
$cur->emailChanged(); $cur->emailChanged();
} }
} else { } else {
$user_im_prefs = new User_im_prefs(); $user_im_prefs = new User_im_prefs();
$user_im_prefs->transport = $confirm->address_type; $user_im_prefs->transport = $confirm->address_type;
$user_im_prefs->user_id = $cur->id; $user_im_prefs->user_id = $cur->id;
if ($user_im_prefs->find() && $user_im_prefs->fetch()) { if ($user_im_prefs->find() && $user_im_prefs->fetch()) {
if ($user_im_prefs->screenname === $confirm->address) { if($user_im_prefs->screenname == $confirm->address){
// Already verified, so delete the confirm_address entry // Already verified, so delete the confirm_address entry
$confirm->delete(); $confirm->delete();
// TRANS: Client error for an already confirmed IM address. // TRANS: Client error for an already confirmed IM address.
@@ -129,7 +135,7 @@ class ConfirmaddressAction extends ManagedAction
// TRANS: Server error displayed when updating IM preferences fails. // TRANS: Server error displayed when updating IM preferences fails.
throw new ServerException(_('Could not update user IM preferences.')); throw new ServerException(_('Could not update user IM preferences.'));
} }
} else { }else{
$user_im_prefs = new User_im_prefs(); $user_im_prefs = new User_im_prefs();
$user_im_prefs->screenname = $confirm->address; $user_im_prefs->screenname = $confirm->address;
$user_im_prefs->transport = $confirm->address_type; $user_im_prefs->transport = $confirm->address_type;
@@ -143,6 +149,7 @@ class ConfirmaddressAction extends ManagedAction
throw new ServerException(_('Could not insert user IM preferences.')); throw new ServerException(_('Could not insert user IM preferences.'));
} }
} }
} }
$confirm->delete(); $confirm->delete();
@@ -155,7 +162,7 @@ class ConfirmaddressAction extends ManagedAction
* *
* @return string title * @return string title
*/ */
public function title() function title()
{ {
// TRANS: Title for the contact address confirmation action. // TRANS: Title for the contact address confirmation action.
return _('Confirm address'); return _('Confirm address');
@@ -166,17 +173,13 @@ class ConfirmaddressAction extends ManagedAction
* *
* @return void * @return void
*/ */
public function showContent() function showContent()
{ {
$this->element( $this->element('p', null,
'p',
null,
// TRANS: Success message for the contact address confirmation action. // TRANS: Success message for the contact address confirmation action.
// TRANS: %s can be 'email', 'jabber', or 'sms'. // TRANS: %s can be 'email', 'jabber', or 'sms'.
sprintf( sprintf(_('The address "%s" has been '.
_('The address "%s" has been confirmed for your account.'), 'confirmed for your account.'),
$this->address $this->address));
)
);
} }
} }

Some files were not shown because too many files have changed in this diff Show More