Welcome to Geeklog Thursday, November 23 2017 @ 09:18 pm EST


Status: offline

TimPatrick

Forum User
Newbie
Registered: 20/04/2009
Posts: 5
caffeinated
Hey Guys,

My name is Tim Patrick, and through Google Summer of Code I will be working on implementing a plugin repository with the goals of having easy one click installation of all plugins, modeled off the package manager Synaptic for Linux.

Since I am not only developing this system for the users but also for the plugin developers, I would like your input in what you would like to see in the whole plugin management, as I want to make something that you guys want to use, and not something that annoys and frustrates you so much you will want to kill me Razz

I will briefly go over my idea: (Actually I just copied most of it from my proposal Wink )
The repositories exist of two types - public and private.

Public repositories, allow anyone to upload plugins to the repository. An option can be configured, which prevents the plugin from being displayed until a moderator verifies its integrity.

Private repositories, on the other hand, only allow specific users to upload plugins to the repository.
These would be optionally approved by a moderator, depending on a configuration value in the conf_values table. As well, private repositories can also limit who is able to connect to and download from their repository. This would be accomplished by a unique key hash that would be downloaded to an approved site, that would log the site in and verify it. These key hashes would be stored in the repository database.
As mentioned in the mailing list, there was some question as to why an administrator would require this functionality. In my opinion it is always better to allow for new functionality, instead of limiting the potential.
An administrator may want this functionality because they only want to develop a plugin for a friend or for a group of people. However this does go against the concept of open source, so it may be better not to implement it at all.

Verification:
To verify that the plugins are safe, the main Geeklog repository will digitally sign the plugin to guarantee that the plugin is genuine. When a plugin is selected to be downloaded, if no verification is present, a warning will be displayed that alerts the administrator that the plugin may be malicious, and to click OK to consent to install it. For digitally signed plugins, the installer will determine if the signing is valid and from Geeklog, and then install the plugin. If however the signing is not valid, it will act as if the plugin is not signed at all and display a warning like above. For an example of this model, the Mozilla Add-ons site is a good example.

The reason digital signing is better than a checksum, as digital signing verifies that the plugin is not malicious, and is authenticated by the main Geeklog site. Checksumming, on the other hand, simply verifies that the integrity of the data has not been modified, which doesn't care if the data is malicious or not, but simply if it has been modified.

Blacklisting:
Repositories that contain malicious plugins can be black listed by the main Geeklog site. This would work much like Google's blacklisting for malicious sites. Users would be able to alert Geeklog of malicious repositories, and if Geeklog verified these as malicious, would be added to the Blacklist. This list would be downloaded every time the plugin manager is started, and if a user attempts to install from one of these malicious repositories, they would be alerted of the danger, and the reason the site was black listed. However they would not be prevented from installing a plugin from that repository if they wanted to.
As well, if they had a blacklisted repository in their repository list, a warning would be displayed every time the user started the plugin manager, with a request to delete the offending repository from the list.

How the repository works:
The repository consists of two separate sections. One is a database table that contains the locations of the plugins that are available, as well as other revelant data (name, documentation, etc). The other section actually holds the plugin data. Addition of a plugin is simple, using the addition tool, that will allow a repository administrator to either upload a new plugin, or verify a submitted plugin, which then will copy the plugin data to the plugin data section, while adding an entry to the plugin repository database.
Deletion from the repository works the other way, where the plugin is removed from the plugin section, and the entry is removed from the repository database.
Updates to any plugins are stored in the updates section, and listed in the updates database. The updates database state the files that have to be updated in the plugin, as well as the location of that update.


Plugin Manager:
The plugin manager, modelled off Synaptic (GNOME Package Manager that uses apt-get for Linux), would be where the administrator would be able to install plugins from the repositories. It also allows you to check for updates, and install them, as well as remove any plugins installed by the manager.

Adding and Removing Plugins:
The plugin manager has a list of repository locations, which can have repositories added or removed from the list. When the plugin manager is loaded, the repositories are checked for any new plugins, and the list of the plugins is then displayed. These plugins have a description as well with them. (Much like how synaptic works).
The administrator can then check the check box next to each plugin he/she wants added, or un-check checked boxes to remove them.
The administrator then would click to submit changes, and if removing any, a warning would be shown for each one to be removed.

When the plugin manager loads, the user is given a choice to either scroll through all listed plugins, or search through the entire plugin database. This search is not only for a name, but for keywords about the plugins functionality.
As well, plugins can be grouped according to plugin type, for example: Multimedia, Time Tracking, etc.


Update Manager:
The update manager is called from the plugin manager, and checks the repository update list for any new updates. If some are found, the user is notified of the update, as well as the severity of the update. (Eg. High Security Update). The user can then uncheck updates they do not want installed, and then can hit the update buttons to have the update performed. The updates are performed by reading the update file, and then downloading the appropriate files and overwriting the existing ones based on the instructions in the update file.

To make sure that once an update has been installed, the update is no longer shown as needing to be installed, once the update list is downloaded from the repository, each updates' unique id (AUTO_INCREMENT field) is checked against the updated table, that lists every update that has already been applied by their unique id. If an updates's unique id is in the updated table, that update is not displayed.

Perhaps this method of updating plugins can be modified to allow for Geeklog updates to the various sites, much like how the Update Manager in Linux will update to a new distribution.

-- End Proposal


My idea was that every plugin would have a configuration file that has the steps for installation, removal, etc which the plugin manager will then simply read and execute.
eg.

PHP Formatted Code

file:: myplugin.config.inst


<install>
getxtract myplugin/plugin.tar.gz
mov pass.txt $ROOT/pass.txt
rename srclib
db.create_table myplugintbl.sql
db.add_rows mypluginrows.sql
db.add_rows conf_rows.sql
</install>


file:: myplugin.config.rem

rm $ROOT/pass.txt
db.droptable myplugintbl

 


etc.

This config file would have simple commands (eg. mov, rm, db.create, db.add_rows, db.remove, etc) which allows you the developer to not worry about how the installation process is done, but just lists what commands to perform.

This not only cuts down on development time, but also helps standardize the entire plugin creation process.

Other than that one file the plugin developer would have total liberty to have whatever other structure he/she wants in the plugin directory. As long as the configuration file is there.

Plugins are stored in the repository server as a folder with the config files in it (install, remove, ..) and the tar ball that contains the plugin data as well as any other data.
As in the installation process, the gextract command would get the tar ball, extract it to the plugin directory, and then run commands from the install file it has loaded from the repository.
This allows the plugin manager to simply get the config file for the action (eg. install or remove) and then following its directions only download what is needed (and in the removal process, only the config file).

This cuts down on network bandwidth and also speed of installation and removal. Plus it saves space in the database where before removal, installation, etc instructions would have to be stored for each plugin.

Anyways I would like to know your thoughts and suggestions with this idea?
Ideas, improvements? Criticism Razz?

Also how do you like the current GL plugin system. If you had the time what would you do to improve it? What have you always wanted or wished was never there?

- Tim





Status: offline

beewee

Forum User
Full Member
Registered: 05/08/2003
Posts: 969
Location:The Netherlands, where else?
It would be nice if the plugin installer would ask for the configuration options during install. Now you have to install a plugin, and set the configuration afterwards. But after install, the plugin is already online, so it would be nice if it´s configured during installation.
Dutch Geeklog sites about camping/hiking: www.kampeerzaken.nl | www.campersite.nl | www.caravans.nl | www.caravans.net

Status: offline

LWC

Forum User
Full Member
Registered: 19/02/2004
Posts: 818
Quote by: TimPatrick

Also how do you like the current GL plugin system. If you had the time what would you do to improve it? What have you always wanted or wished was never there?


There's currently no way to delete plugins from geeklog.net. I assume it's because the admins want to make sure plugin authors don't delete plugins for old Geeklog versions. But this means bad versions must remain public forever. It's too much like a wiki in that sense (even the most minor revision - even if it was replaced seconds later - must be kept forever).

I think the only versions that must remain are those that were made for older Geeklog versions. Alas, the filemgmt plugin was not made specifically for Geeklog related downloads. That's why it has no "version of Geeklog the plugin was made for" selection box (like the tracker has).

Status: offline

Dirk

Site Admin
Admin
Registered: 12/01/2002
Posts: 13073
Location:Stuttgart, Germany
Quote by: LWC

There's currently no way to delete plugins from geeklog.net. I assume it's because the admins want to make sure plugin authors don't delete plugins for old Geeklog versions.


It's more due to the fact that the File Management plugin doesn't really offer a lot of options for actual management ... We tried to account for these things in the design of the plugin repository.

bye, Dirk

Tim Patrick

Anonymous
[quote=beewee]
It would be nice if the plugin installer would ask for the configuration options during install. Now you have to install a plugin, and set the configuration afterwards. But after install, the plugin is already online, so it would be nice if it´s configured during installation.
[/quote]

Yes that is a another plan.

There would be a standard config-set page for each plugin, that would dictate what to ask.
I am not sure of the best way to do it -
My idea here would be:

a set-config page that would list the fields, default values, and a unique_id for each field.
There would be a corresponding libsetconfig written by the developer.
The libsetconfig would contain one class (or function but I think the class is better) which would be:
setconfig() and take in an array of the values from the fields specified in the set-config page. (eg. $array["some_config"] = valueWink

So this would allow a set-config page like this:

PHP Formatted Code

type text msg "Set color" default 0 id set_color9257825
 


the HTML generated by the plugin repository would be:

PHP Formatted Code

<div>Set Color</div>
<input type="text" name="set_color9257825" value="0" />
 


When the form is filled and submitted, the plugin repository would then get the post values for the ids (eg. $_POST['set_color9257825']), put them into an array ($array['set_color9257825'] = valueWink and then call the libsetconfig function or class with the array as the first parameter.
l = libsetconfig();
l.run($array);


- How does that sound? Do you guys have a better idea? Do you like the idea of forced standards?

And @ LWC the repository will allow deletion, addition, etc so that will be an issue of the past Wink

- Tim

Status: offline

jmucchiello

Forum User
Full Member
Registered: 29/08/2005
Posts: 985
One thing to remember is there will be some people who will insist on NOT using the plugin repository. They will want to download the zip, extract the files, move them to the website and run the install from the admin interface. Thus, the plugin MUST be able to install itself without the fancy repository code.
Quote by: TimPatrick


This config file would have simple commands (eg. mov, rm, db.create, db.add_rows, db.remove, etc) which allows you the developer to not worry about how the installation process is done, but just lists what commands to perform.


Plugins already know how to modify the database during install. Why reinvent the wheel? The only thing this config file really needs to do is say where to move files. Wouldn't it be easier on the plugin dev to simply require a file manifest? About the only other command that would be need would be chmod type thing.
PHP Formatted Code

$zip/$plugin/functions.inc           $geeklog/plugins/$plugin/functions.inc
$zip/$plugin/public_html/index.php   $geeklog/public_html/$plugin/index.php
 


beewee: In theory, the /public_html/admin/plugins/$Plugin/install.php file would be where you put pre-install configuration in the current setup. admin/plugins.php puts that install link on the screen. That link is just a call to the plugin's install.php with an install parameter. Nothing stopping you from putting up a "hey, set these params before I start" screen and then have the form submit do the actual install. No one really does it. But it's there.
PHP Formatted Code

// MAIN  -- look at calendar/install.php or links/install.php for the next two lines
$display = '';

if ($_REQUEST['action'] == 'uninstall') {
...
// then modify it like this
} else if ($_REQUEST['action'] == 'install') {
    $display = show_preconfig_options();
} else if ($_POST['submit'] == 'submit') {
    $display = do_real_install($_POST);
}
 


When the form is filled and submitted, the plugin repository would then get the post values for the ids (eg. $_POST['set_color9257825']), put them into an array ($array['set_color9257825'] = valueWink and then call the libsetconfig function or class with the array as the first parameter.
l = libsetconfig();
l.run($array);


As you've seen above, there is already a way for the plugin to do this that doesn't require writing to the database. Your method runs afoul of the failed plugin install. Who cleans up the database? How?

As you can guess I'm not a fan of enforced standards.

Status: offline

Dirk

Site Admin
Admin
Registered: 12/01/2002
Posts: 13073
Location:Stuttgart, Germany
nerdy
/me points everybody at the Plugin Autoinstall in Geeklog 1.6 ...

Status: offline

1000ideen

Forum User
Full Member
Registered: 04/08/2003
Posts: 1289
Hi Tim Patrick, thanks for discussing this here :shakehands: although in the "Developers Only" forum which I recommended to be renamed to "Meet the Developers" sometime ago.


Erm, what is a plugin? WHY only plugins? Geeklog has language packs and also blocks too. Several plugins come without multilingual translation. It would be nice to be able to download it too. Also the blocks, or anything that is now being offered for download.

What about bridges? http://www.flashyourweb.com/staticpages/index.php?page=g2bridge_readme

What is the main Geeklog site? As geeklog.net does not have multilingual subsections there are several main sites e.g. in Japan.

What will you do with buggy plugins, will they be 'verified'? Probably yes, but blacklisted.

As for me I consider this a complete overkill. Geeklog does not have many plugins which are worthwhile or necessary to stop spam. A good listing and overview is sufficient and no more technology. A complete set of Geeklog including the major plugins would be a good and simple alternative. As Joe said it should be optional at any rate and not compulsory Idea

On the other hand especially fantastico users will profit from more automatic and thus GL will have a new user group.

Status: offline

TimPatrick

Forum User
Newbie
Registered: 20/04/2009
Posts: 5
Quote by: 1000ideen

Hi Tim Patrick, thanks for discussing this here :shakehands: although in the "Developers Only" forum which I recommended to be renamed to "Meet the Developers" sometime ago.


Erm, what is a plugin? WHY only plugins? Geeklog has language packs and also blocks too. Several plugins come without multilingual translation. It would be nice to be able to download it too. Also the blocks, or anything that is now being offered for download.

What about bridges? http://www.flashyourweb.com/staticpages/index.php?page=g2bridge_readme

What is the main Geeklog site? As geeklog.net does not have multilingual subsections there are several main sites e.g. in Japan.

What will you do with buggy plugins, will they be 'verified'? Probably yes, but blacklisted.

As for me I consider this a complete overkill. Geeklog does not have many plugins which are worthwhile or necessary to stop spam. A good listing and overview is sufficient and no more technology. A complete set of Geeklog including the major plugins would be a good and simple alternative. As Joe said it should be optional at any rate and not compulsory Idea

On the other hand especially fantastico users will profit from more automatic and thus GL will have a new user group.



The way I will be developing it will be that it will work with *any* module based item (eg. plugins, language packs, etc.)
That is the reason I was hoping for a standard installation language script.. But it could be done without it.

By the main Geeklog site, I meant a trusted Geeklog domain that would hold the 'trusted' digitally signed plugins that have been approved to be ok.
I plan to follow Synaptic Manager for the general operation, as such, buggy plugins will not be an issue.
This is because they will be located in a 'buggy' repository, unstable in another, tested and tried in another.
See when a repository is created, they can choose a name and a warning message (if needed) for it to be displayed.

The whole idea behind the plugin repository is imho to develop two goals:
- A convenient way for developers to get their plugins into the main stream user base. (How easy is it to search 'Forums' in the search bar and be given a list of plugins from which to choose with information about each one)

And
Allow users an easy and quick way to install functionality to their site.

I find myself as programmers we tend to think of installing something we made or understand well (eg. plugin development) as very easy, however to the simple user this is far from the case. For example when I first started playing around with plugins the installation and that was a pain, and a few times I decided not to bother as it seemed like so much work and files were all over the place etc.
And added to the fact that most users are probably not the most technical literate (eg. Knows basic server structure but do not know how to move files around and install it. ) It seems so confusing to them to follow the install instructions.

(Which is when you install a windows app you do not have to compile it, move the files, and add registry keys. To a windows developer who knows everything about this process this seems like an easy simple task but to us the users we would go crazy. Smile Well maybe not us cause we are programmers but think of someone not as literate in computer programming. The aim is to allow them to use the site as well).
(And the usual disclaimer - The views expressed here are those of Tim Patrick and do not necessary reflect the views and / or opinions of Geeklog Razz Razz Razz Razz Razz Razz Razz )

As for compulsory, I think enforcing a standard if they want to include in the repository is the best route to go, however if they do not I do not see why any standards would have to be enforced. The only reason for a standard for the repository is to allow the manager to successfully interact with the plugin.
Maybe in the repository we can also have a repository of non automatically installing plugins that the user can download and then manually install. This would work with plugins the user wants to customize etc.

- Tim

Status: offline

suprsidr

Forum User
Full Member
Registered: 29/12/2004
Posts: 555
Location:Champaign, Illinois
Tim, good to meet you - glad you are on the case Wink

[ :twocents: ]
@transfer/download methods
You'll need to test the platform before defaulting to wget.
For Gallery2 we are aware of the platform for all filesystem methods.
Take a look at the preinstaller for example. It tests the platform, checks for available methods and binaries for downloading/unzipping...
But you are still likely to need the end user to change directory permissions to allow writing and copying files to and fro

You may also want to take a look at Gallery2's module/install/upgrade/repository model its very effective for a web based multi-platform application.

Currently I keep my plugins available from my site only for better version control. And if you make it too difficult for a developer to upload and share his/her plugin they may not participate.
So I'm all for keeping some legacy installation abilities.

XML mapping for manifest purposes would be logical and you could list install/upgrade/uninstall methods there as well.
[/ :twocents: ]

-s
FlashYourWeb and Your Gallery with the E2 XML Media Player for Gallery2 - http://www.flashyourweb.com

Status: offline

Dirk

Site Admin
Admin
Registered: 12/01/2002
Posts: 13073
Location:Stuttgart, Germany
Quote by: 1000ideen

As for me I consider this a complete overkill. Geeklog does not have many plugins which are worthwhile or necessary to stop spam. A good listing and overview is sufficient and no more technology.


Hmm. We're getting complaints about the plugin install being to complicated all the time. Now we're aiming for a really easy way (think "one-click install" ) and suddenly it's overkill? Remember that this would also include plugin updates.


Quote by: 1000ideen

A complete set of Geeklog including the major plugins would be a good and simple alternative.


As I've said before (and despite the addition of a sixth plugin in 1.6.0), I'd rather reduce the number of plugins bundled with Geeklog. Instead, make it easier to create your own "Geeklog distro" where you can throw in any plugin you'd like. 1.6.0 allows that.

Plugins have their own release schedules. Syncing that with the Geeklog releases would be a huge headache and a lot of work (e.g. providing updated tarballs when a new version of one of the bundled plugins come out). Instead, there would be a somewhat stripped-down Geeklog "core distro" on our usual long-term schedule and a few community-driven "value-added" distros that include the latest and greatest plugins and would be updated more frequently.

And in addition to that, the Plugin Repository would make it easy to install and update any plugin you want at any time.

bye, Dirk

Status: offline

1000ideen

Forum User
Full Member
Registered: 04/08/2003
Posts: 1289
Quote by: TimPatrick

Maybe in the repository we can also have a repository of non automatically installing plugins that the user can download and then manually install. This would work with plugins the user wants to customize etc.


I rather meant I want to have the manual control over plugins as well. So maybe an option 1 install plugin 2 download on harddisk and manually install.

@Dirk: sure the current way of finding, distributing, packing, describing, translating plugins and blocks is a desaster. I just meant this is not a matter of technology.

Geeklog is not as big a GNOME which was mentioned before. Geeklog has a handful of useful or necessary plugins.


Anyway I`m not against this I just pointed out both positions. Also don`t forget fantastico users and make sure the repository will also install into their non standard installations.

Status: offline

TimPatrick

Forum User
Newbie
Registered: 20/04/2009
Posts: 5
Just for clarification, how do the fantastico installations differ?
Wouldn't the document tree be the same, or is it changed? Are there different permissions?

@suprsidr:
I wouldn't be using wget, as it is platform dependent. Instead use probably the PEAR HTTP_Request as it would be the logical choice and since as Dirk mentioned in the email they use it in other places it would keep with the coding standard.


Quote by: suprsidr
Currently I keep my plugins available from my site only for better version control. And if you make it too difficult for a developer to upload and share his/her plugin they may not participate.
So I'm all for keeping some legacy installation abilities.



Each site has the option to create a repository. This means you could create your own repository (suprsidr_complete for example) which people can then add the address (yoursite.com/repositories/suprsidr_complete/) to their list of repositories, and then when they search your packages will come up.
So in fact it is very very easy for developers to share their work.

[uQuote by: ]1000ideen[/u]
I rather meant I want to have the manual control over plugins as well. So maybe an option 1 install plugin 2 download on harddisk and manually install.


Yes that would be included eg. Automatically install, or download package and manually install.

Quote by: 1000ideen
Geeklog is not as big a GNOME which was mentioned before. Geeklog has a handful of useful or necessary plugins.


No not at the moment, but it is always better to plan ahead instead of having to recreate the platform because it was designed too small.
And the idea here is to have a quick and easy plugin deployment method to attract development and use of plugins.


The main idea here is not to leave any old plugins etc out in the trash can. It is to provide another method of deployment, which I would hope would be the preferred way. But it would still be possible to extract and install manually the way it is done now.
Much how you can download an open office binary and install it or download the source, and compile it by hand.

- Tim

Status: offline

jmucchiello

Forum User
Full Member
Registered: 29/08/2005
Posts: 985
Quote by: TimPatrick

Just for clarification, how do the fantastico installations differ?



You just made all of us who've ever tried to help someone install Geeklog groan. Fantastico installations are notoriously setup improperly and cause all sorts of upgrade nightmares. Geeklog has never been consulted by Fantastico to create an installation and anyone who shows up in the forums asking about Fantastico is strongly advised to do the install on their own without Fantastico.

Status: offline

jmucchiello

Forum User
Full Member
Registered: 29/08/2005
Posts: 985
Quote by: 1000ideen

Erm, what is a plugin? WHY only plugins? Geeklog has language packs and also blocks too. Several plugins come without multilingual translation. It would be nice to be able to download it too. Also the blocks, or anything that is now being offered for download.



That's not really fair. There is no standard distribution method for language packs or blocks. I'd be surprised if he could do the repository and create standards for block and language distribution all over this one summer. Just getting plugins to install straight from a repository would be a good first start. Then he can add themes (which mostly have a standard archive) and then probably next summer someone could work to add other objects.

But first there would need to be a "standard Geeklog language pack" archive format and that doesn't exist just yet. And since it doesn't exist, it's premature to ask him whether he'll support it.

Status: offline

::Ben

Forum User
Full Member
Registered: 14/01/2005
Posts: 1569
Location:la rochelle, France
:shakehands: Tim Patrick

+1 for this
Maybe in the repository we can also have a repository of non automatically installing plugins that the user can download and then manually install. This would work with plugins the user wants to customize etc.
because we need it too.

An what about downgrade, would it be possible for the plugins manager to delete the last version of a plugin and come back to an old one?

Thanks,

::Ben
I'm available to customise your themes or plugins for your Geeklog CMS

Tim Patrick

Anonymous
By Cordiste

An what about downgrade, would it be possible for the plugins manager to delete the last version of a plugin and come back to an old one?


It all depends. As the owner of the repository you can elect to keep older versions available for download. (eg. MyPlugin v. 0.1, 1.2 etc).

Hence the user can uninstall the MyPlugin currently installed, and then install an older version.

Unless there is some standards we make (config file again Razz ) which lists the version there is no way for the installer to know which version is the one you have.

- Tim

Status: offline

::Ben

Forum User
Full Member
Registered: 14/01/2005
Posts: 1569
Location:la rochelle, France
Tim,

I try an exemple to explain what I'm looking for. Sorry for my english.

A new version for my cool plugin is available. I make the upgrade but when I use this new version I'm not happy. A new feature is not for me and I can't disable it, or my old features are gone Evil

Can I downgrade without loosing datas witch are not store in the db but in folders like some plugins do (dokuwiki, mediagallery, filemgmt...)

Thanks,

::Ben
I'm available to customise your themes or plugins for your Geeklog CMS

Status: offline

jmucchiello

Forum User
Full Member
Registered: 29/08/2005
Posts: 985
Ben, isn't that an issue of the plugin itself? Most plugins are not designed with downgrading in mind. How would the repository help in this regard? What could it to do that would help in this case?

Status: offline

::Ben

Forum User
Full Member
Registered: 14/01/2005
Posts: 1569
Location:la rochelle, France
Hello Joe,

I was thinking to new users (geeklog 1.6 and higher) who need to downgrade (I never needed this feature Smile ) and he do not known nothing about manual upgrade or downgrade.

But after all, maybe the plugin manager can downgrade a plugin with the upgrade function if we choose an older version?

::Ben
I'm available to customise your themes or plugins for your Geeklog CMS

All times are EST. The time is now 09:18 pm.

  • Normal Topic
  • Sticky Topic
  • Locked Topic
  • New Post
  • Sticky Topic W/ New Post
  • Locked Topic W/ New Post
  •  View Anonymous Posts
  •  Able to post
  •  Filtered HTML Allowed
  •  Censored Content