Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

geniuspaste: Update pastebins #551

Merged
merged 5 commits into from
Apr 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions geniuspaste/README
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ services, but more can be added:
* pastebin.geany.org
* paste.debian.net
* sprunge.us
* tinypaste.com

GeniusPaste detects automatically the syntax of the code and pastes it
with syntax highlighting enabled.
Expand Down Expand Up @@ -67,7 +66,7 @@ Placeholders

Values from the `[format] section`_ and the *replace* key in the `[parse]
section`_ can contain references to placeholders with the syntax ``%name%``
(i.e. ``%contents%``).
(e.g. ``%contents%``).
Custom placeholders can be defined in the `[defaults] section`_.

The builtin placeholders are:
Expand Down Expand Up @@ -95,6 +94,10 @@ The *pastebin* section is required, and must contain at least the *name* and
The URL to which submit the data. This key is required.
*method*
The HTTP method to use to submit the data. Defaults to ``POST``.
*content-type*
The Content-Type the request body should be sent in. Currently supported
types include ``application/x-www-form-urlencoded`` and ``application/json``.
Defaults to ``application/x-www-form-urlencoded``.

*[format]* section
++++++++++++++++++
Expand All @@ -121,7 +124,7 @@ enable response body parsing, and it will use the default *search* and
*search*
A regular expression (PCRE) pattern to match against the pastebin
service's raw response data.
Defaults to ``^[[:space:]]*(.+?)[[:space:]]*$``, e.g. capture everything
Defaults to ``^[[:space:]]*(.+?)[[:space:]]*$``, i.e. capture everything
but the leading and trailing whitespaces.
*replace*
The final URL, with regular expression capture groups from *search*
Expand Down
3 changes: 1 addition & 2 deletions geniuspaste/data/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ dist_pastebins_DATA = \
fpaste.org.conf \
pastebin.geany.org.conf \
paste.debian.net.conf \
sprunge.us.conf \
tinypaste.com.conf
sprunge.us.conf
4 changes: 2 additions & 2 deletions geniuspaste/data/dpaste.de.conf
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[pastebin]
name=dpaste.de
url=http://dpaste.de/api/
url=https://dpaste.de/api/

[format]
title=%title%
filename=%title%
content=%contents%
lexer=%language%
#expires=%expire%
Expand Down
98 changes: 43 additions & 55 deletions geniuspaste/data/fpaste.org.conf
Original file line number Diff line number Diff line change
@@ -1,67 +1,55 @@
[pastebin]
name=fpaste.org
url=http://fpaste.org/
url=https://paste.fedoraproject.org/api/paste/submit
content-type=application/json

[format]
paste_data=%contents%
paste_lang=%language%
api_submit=true
mode=xml
contents=%contents%
language=%language%
title=%title%

# Optional stuff

paste_user=%user%
# expiration in seconds
#paste_expire=0
# expiration date in UNIX timestamp
#expiry_time=1453355837
# Password for accessing the paste
#password=password123

[parse]
search=<id>(.+?)</id>
replace=http://fpaste.org/\1
search="url" *: *"([^"]+)"
replace=\1

# map GeanyFileType=PastebinFileType
[languages]
# map for GeSHi 2015-01-14
ActionScript=Actionscript
Ada=ADA
ASM=ASM
C=C
C#=C#
C++=C++
COBOL=COBOL
Conf=INI
CSS=CSS
CUDA=C
Cython=Python
D=D
Diff=Diff
Docbook=XML
F77=Fortran
Fortran=Fortran
FreeBasic=FreeBasic
GLSL=C
Haskell=Haskell
HTML=HTML
Java=Java
Javascript=Javascript
JSON=Javascript
LaTeX=LaTeX
Lisp=Lisp
Lua=Lua
Make=Make
NSIS=NSIS
Objective-C=Objective-C
Pascal=Pascal
Perl=Perl
PHP=PHP
Po=GetText
PowerShell=PowerShell
Prolog=Prolog
Python=Python
Ruby=Ruby
Scala=Scala
Sh=Bash
SQL=SQL
Tcl=TCL
Verilog=Verilog
VHDL=VHDL
XML=XML
# based off the list on the pastebin's web frontend
CMake=cmake
CoffeeScript=coffeescript
CSS=css
D=d
Diff=diff
Elm=elm
Erlang=erlang
Factor=factor
F77=fortran
Fortran=fortran
Go=go
Haskell=haskell
HTML=htmlmixed
Javascript=javascript
Jinja2=jinja2
Markdown=markdown
Matlab/Octave=octave
PHP=php
Python=python
RPM=rpm
Ruby=ruby
Rust=rust
SASS=sass
Sh=shell
Smalltalk=smalltalk
SQL=sql
Swift=swift
Verilog=verilog
VHDL=vhdl
XML=xml
YAML=yaml
20 changes: 0 additions & 20 deletions geniuspaste/data/tinypaste.com.conf

This file was deleted.

133 changes: 118 additions & 15 deletions geniuspaste/src/geniuspaste.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,17 @@
#define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX
#endif

#define PASTEBIN_GROUP_DEFAULTS "defaults"
#define PASTEBIN_GROUP_FORMAT "format"
#define PASTEBIN_GROUP_LANGUAGES "languages"
#define PASTEBIN_GROUP_PARSE "parse"
#define PASTEBIN_GROUP_PARSE_KEY_SEARCH "search"
#define PASTEBIN_GROUP_PARSE_KEY_REPLACE "replace"
#define PASTEBIN_GROUP_PASTEBIN "pastebin"
#define PASTEBIN_GROUP_PASTEBIN_KEY_NAME "name"
#define PASTEBIN_GROUP_PASTEBIN_KEY_URL "url"
#define PASTEBIN_GROUP_PASTEBIN_KEY_METHOD "method"
#define PASTEBIN_GROUP_DEFAULTS "defaults"
#define PASTEBIN_GROUP_FORMAT "format"
#define PASTEBIN_GROUP_LANGUAGES "languages"
#define PASTEBIN_GROUP_PARSE "parse"
#define PASTEBIN_GROUP_PARSE_KEY_SEARCH "search"
#define PASTEBIN_GROUP_PARSE_KEY_REPLACE "replace"
#define PASTEBIN_GROUP_PASTEBIN "pastebin"
#define PASTEBIN_GROUP_PASTEBIN_KEY_NAME "name"
#define PASTEBIN_GROUP_PASTEBIN_KEY_URL "url"
#define PASTEBIN_GROUP_PASTEBIN_KEY_METHOD "method"
#define PASTEBIN_GROUP_PASTEBIN_KEY_CONTENT_TYPE "content-type"

GeanyPlugin *geany_plugin;
GeanyData *geany_data;
Expand All @@ -73,6 +74,13 @@ typedef struct
}
Pastebin;

typedef enum
{
FORMAT_HTML_FORM_URLENCODED,
FORMAT_JSON
}
Format;

GSList *pastebins = NULL;

static struct
Expand Down Expand Up @@ -503,9 +511,93 @@ static gchar *regex_replace(const gchar *pattern,
return result;
}

static void free_data_item(GQuark id, gpointer data, gpointer user_data)
static Format pastebin_get_format(const Pastebin *pastebin)
{
g_free(data);
static const struct
{
const gchar *name;
Format format;
} formats[] = {
{ "application/x-www-form-urlencoded", FORMAT_HTML_FORM_URLENCODED },
{ "application/json", FORMAT_JSON }
};
Format result = FORMAT_HTML_FORM_URLENCODED;
gchar *format = utils_get_setting_string(pastebin->config, PASTEBIN_GROUP_PASTEBIN,
PASTEBIN_GROUP_PASTEBIN_KEY_CONTENT_TYPE, NULL);

if (format)
{
for (guint i = 0; i < G_N_ELEMENTS(formats); i++)
{
if (strcmp(formats[i].name, format) == 0)
{
result = formats[i].format;
break;
}
}

g_free(format);
}

return result;
}

/* Appends a JSON string. See:
* http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf */
static void append_json_string(GString *str, const gchar *value)
{
g_string_append_c(str, '"');
for (; *value; value++)
{
if (*value == '"' || *value == '\\')
{
g_string_append_c(str, '\\');
g_string_append_c(str, *value);
}
else if (*value == '\b')
g_string_append(str, "\\b");
else if (*value == '\f')
g_string_append(str, "\\f");
else if (*value == '\n')
g_string_append(str, "\\n");
else if (*value == '\r')
g_string_append(str, "\\r");
else if (*value == '\t')
g_string_append(str, "\\t");
else if (*value >= 0x00 && *value <= 0x1F)
g_string_append_printf(str, "\\u%04d", *value);
else
g_string_append_c(str, *value);
}
g_string_append_c(str, '"');
}

static void append_json_data_item(GQuark id, gpointer data, gpointer user_data)
{
GString *str = user_data;

if (str->len > 1) /* if there's more than the first "{" */
g_string_append_c(str, ',');
append_json_string(str, g_quark_to_string(id));
g_string_append_c(str, ':');
append_json_string(str, data);
}

static SoupMessage *json_request_new(const gchar *method,
const gchar *url,
GData **fields)
{
SoupMessage *msg = soup_message_new(method, url);
GString *str = g_string_new(NULL);

g_string_append_c(str, '{');
g_datalist_foreach(fields, append_json_data_item, str);
g_string_append_c(str, '}');
soup_message_set_request(msg, "application/json", SOUP_MEMORY_TAKE,
str->str, str->len);
g_string_free(str, FALSE);

return msg;
}

/* sends data to @pastebin and returns the raw response */
Expand All @@ -516,6 +608,7 @@ static SoupMessage *pastebin_soup_message_new(const Pastebin *pastebin,
SoupMessage *msg;
gchar *url;
gchar *method;
Format format;
gsize n_fields;
gchar **fields;
GData *data;
Expand All @@ -527,6 +620,7 @@ static SoupMessage *pastebin_soup_message_new(const Pastebin *pastebin,
PASTEBIN_GROUP_PASTEBIN_KEY_URL, NULL);
method = utils_get_setting_string(pastebin->config, PASTEBIN_GROUP_PASTEBIN,
PASTEBIN_GROUP_PASTEBIN_KEY_METHOD, "POST");
format = pastebin_get_format(pastebin);
/* prepare the form data */
fields = g_key_file_get_keys(pastebin->config, PASTEBIN_GROUP_FORMAT, &n_fields, NULL);
g_datalist_init(&data);
Expand All @@ -536,11 +630,20 @@ static SoupMessage *pastebin_soup_message_new(const Pastebin *pastebin,
fields[i], NULL);

SETPTR(value, expand_placeholders(value, pastebin, doc, contents));
g_datalist_set_data(&data, fields[i], value);
g_datalist_set_data_full(&data, fields[i], value, g_free);
}
g_strfreev(fields);
msg = soup_form_request_new_from_datalist(method, url, &data);
g_datalist_foreach(&data, free_data_item, NULL);
switch (format)
{
case FORMAT_JSON:
msg = json_request_new(method, url, &data);
break;

default:
case FORMAT_HTML_FORM_URLENCODED:
msg = soup_form_request_new_from_datalist(method, url, &data);
break;
}
g_datalist_clear(&data);

return msg;
Expand Down