upload
95
API.php
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
include 'settings.php';
|
||||
|
||||
header("Content-type: application/json; charset=utf-8");
|
||||
if(substr($apiroot,-1) != '/') { $apiroot .= '/'; } // add slash if missing
|
||||
|
||||
// post requests
|
||||
if(isset($_POST['postRequest'])) {
|
||||
$query = http_build_query($_POST, '', '&');
|
||||
$ch=curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $apiroot.urldecode($_POST['postRequest']));
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
|
||||
session_write_close(); // fix problem with curling to local
|
||||
$reply=curl_exec($ch);
|
||||
curl_close($ch);
|
||||
session_start();
|
||||
|
||||
// force ssl on our domain
|
||||
if($forcessl) {
|
||||
$reply = str_replace('http://'.$siterootdomain,'https://'.$siterootdomain,$reply);
|
||||
}
|
||||
|
||||
print $reply;
|
||||
}
|
||||
|
||||
// get requests
|
||||
elseif(isset($_POST['getRequest'])) {
|
||||
$ch=curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $apiroot.$_POST['getRequest']);
|
||||
|
||||
if(isset($_POST['username'])) {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
session_write_close();
|
||||
$reply=curl_exec($ch);
|
||||
curl_close($ch);
|
||||
session_start();
|
||||
|
||||
// force ssl on our domain
|
||||
if($forcessl) {
|
||||
$reply = str_replace('http:\/\/'.$siterootdomain,'https:\/\/'.$siterootdomain,$reply);
|
||||
}
|
||||
|
||||
print $reply;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· (o> >o) ·
|
||||
· \\\\_\ /_//// .
|
||||
· \____) (____/ ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */?>
|
661
LICENSE
Executable file
|
@ -0,0 +1,661 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
76
README.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
Qvitter
|
||||
==========================================
|
||||
|
||||
* Author: Hannes Mannerheim (<h@nnesmannerhe.im>)
|
||||
* Last mod.: August, 2013
|
||||
* Version: 1
|
||||
* Website: <http://beaneditor.org/>
|
||||
* GitHub: <https://github.com/hannesmannerheim/qvitter>
|
||||
|
||||
Qvitter 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 three of the License or (at
|
||||
your option) any later version.
|
||||
|
||||
Qvitter is distributed in hope that it will be useful but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
You need a webserver with PHP support.
|
||||
|
||||
Edit settings.php.
|
||||
|
||||
(Qvitter uses a slightly modified statusnet API. Some things will not work
|
||||
if you connect to a site with standard API. Files are included if you want
|
||||
to Qvitter-mod your Statusnet API.)
|
||||
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
1. Join new external groups and follow new external users
|
||||
|
||||
2. Follow people on other instances
|
||||
|
||||
3. Auto suggest mentions
|
||||
|
||||
4. Register
|
||||
|
||||
5. Background image uploading/editing
|
||||
|
||||
6. Color theme
|
||||
|
||||
7. Auto url-shortening setting under queet box
|
||||
|
||||
10. Settings (e.g. don't show replies to people I don't follow)
|
||||
|
||||
11. Syntax-coloring in queet-box, maybe codemirror (worked nicely for ltr but not rtl text when I tried it)
|
||||
|
||||
12. Image/file upload, drag-n-drop!
|
||||
|
||||
13. Search users
|
||||
|
||||
14. Recommended users
|
||||
|
||||
15. Filters (hide queets containing strings, e.g. mute users)
|
||||
|
||||
18. Better responsive design
|
||||
|
||||
19. More languages
|
||||
|
||||
20. Queet-page
|
||||
|
||||
21. New api for serving _number_ of new items in several streams (to show number of new items in menu/history)
|
||||
|
||||
22. New "expand queet" api for getting conversation, retweets, favs and attachment in the same request
|
||||
|
||||
23. DMs
|
||||
|
||||
24. Node.js long polling server and an new api that serve aggregate of all polling users requests in one go
|
160
api-changes-1.1.1/CHANGES
Normal file
|
@ -0,0 +1,160 @@
|
|||
CHANGES TO API
|
||||
--------------
|
||||
|
||||
* actions/apiattachment.php New api action
|
||||
* actions/apistatusesfavs.php New api action
|
||||
* actions/apicheckhub.php New api action (not used yet)
|
||||
* actions/apiexternalprofileshow.php New api action
|
||||
|
||||
* lib/apiaction.php
|
||||
|
||||
- add urls to larger avatars
|
||||
|
||||
~LINE 213 $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
|
||||
$twitter_user['profile_image_url'] = ($avatar) ? $avatar->displayUrl() :
|
||||
Avatar::defaultImage(AVATAR_STREAM_SIZE);
|
||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$twitter_user['profile_image_url_profile_size'] = ($avatar) ? $avatar->displayUrl() :
|
||||
Avatar::defaultImage(AVATAR_PROFILE_SIZE);
|
||||
$avatar = $profile->getOriginalAvatar();
|
||||
$twitter_user['profile_image_url_original'] = ($avatar) ? $avatar->displayUrl() :
|
||||
Avatar::defaultImage(AVATAR_PROFILE_SIZE);
|
||||
$groups = $profile->getGroups();
|
||||
$groups_count = 0; while($groups->fetch()) $groups_count++;
|
||||
$twitter_user['groups_count'] = $groups_count;
|
||||
|
||||
|
||||
- add the uri-field
|
||||
|
||||
~line 320 $twitter_status['uri'] = $notice->uri;
|
||||
|
||||
|
||||
- show if a notices is favorited by auth_user
|
||||
|
||||
~line 345 if (isset($this->auth_user)) {
|
||||
$this_profile = $this->auth_user->getProfile();
|
||||
$twitter_status['favorited'] = $this->auth_user->hasFave($notice);
|
||||
$twitter_status['repeated'] = $this_profile->hasRepeated($notice->id);
|
||||
} else {
|
||||
$twitter_status['favorited'] = false;
|
||||
$twitter_status['repeated'] = false;
|
||||
}
|
||||
|
||||
|
||||
- show number of admins in group api
|
||||
|
||||
~line 420 $admins = $group->getAdmins();
|
||||
$admin_count = 0; while($admins->fetch()) $admin_count++;
|
||||
$twitter_group['admin_count'] = $admin_count;
|
||||
|
||||
|
||||
- to be able to get group profile by uri.
|
||||
- hackish though, because if uri get-var is sent, it will discard the id get var
|
||||
- (but id still needs to be sent and be non-numerical, so I do "?id=foo&uri={uri}")
|
||||
- should be possible to only supply uri get var, but I was lazy... sry
|
||||
|
||||
~line 1565 } else if ($this->arg('uri')) {
|
||||
return User_group::staticGet('uri', urldecode($this->arg('uri')));
|
||||
|
||||
|
||||
* lib/router.php
|
||||
|
||||
- add routing for new api actions
|
||||
|
||||
~line 467: $m->connect('api/statuses/favs/:id.json',
|
||||
array('action' => 'ApiStatusesFavs',
|
||||
'id' => '[0-9]+'));
|
||||
|
||||
$m->connect('api/attachment/:id.json',
|
||||
array('action' => 'ApiAttachment',
|
||||
'id' => '[0-9]+'));
|
||||
|
||||
$m->connect('api/checkhub.json',
|
||||
array('action' => 'ApiCheckHub'));
|
||||
|
||||
$m->connect('api/externalprofile/show.json',
|
||||
array('action' => 'ApiExternalProfileShow'));
|
||||
|
||||
|
||||
- also, tags need regexp to work with unicode charachters, e.g. farsi and arabic:
|
||||
|
||||
$m->connect('api/statusnet/tags/timeline/:tag.:format',
|
||||
array('action' => 'ApiTimelineTag',
|
||||
'tag' => self::REGEX_TAG,
|
||||
'format' => '(xml|json|rss|atom|as)'));
|
||||
|
||||
|
||||
* acitons/apiconversation.php
|
||||
|
||||
- I didn't always get Profile::current() to show me the auth user's profile, so I changed it to the normal $this->auth_user used in other api actions
|
||||
|
||||
~ line 80: if(isset($this->auth_user)) {
|
||||
$profile = $this->auth_user->getProfile();
|
||||
}
|
||||
else {
|
||||
$profile = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
*actions/apitimelineuser.php
|
||||
|
||||
- this api did only return the public user timeline, not the auth user's.
|
||||
- e.g. it did not show notices from people who post to "my colleques at quitter"
|
||||
- changed to return timeline according to which auth user is requesting
|
||||
|
||||
~ line 238 $user_profile = $this->user->getProfile();
|
||||
if(isset($this->auth_user)) {
|
||||
$auth_user_profile = $this->auth_user->getProfile();
|
||||
}
|
||||
else {
|
||||
$auth_user_profile = null;
|
||||
}
|
||||
|
||||
$stream = new ProfileNoticeStream($user_profile, $auth_user_profile);
|
||||
|
||||
$notice = $stream->getNotices(($this->page-1) * $this->count,
|
||||
$this->count + 1,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
|
||||
|
||||
* search.json
|
||||
|
||||
- changed response to normal twitter format, maybe I should have created a new api action for that,
|
||||
- but... i don't see the point in having a special format for searches, it should be same as other streams
|
||||
|
||||
|
||||
|
||||
* actions/timelinetags.php
|
||||
|
||||
- added max_id and since_id
|
||||
|
||||
~line 179 $notice = Notice_tag::getStream(
|
||||
$this->tag,
|
||||
($this->page - 1) * $this->count,
|
||||
$this->count + 1,
|
||||
$this->since_id,
|
||||
$this->max_id
|
||||
);
|
||||
|
||||
* actions/apistatusesupdate.php
|
||||
|
||||
- we don't want statuses to shorten if sent through the api
|
||||
|
||||
~ line 290: //$status_shortened = $this->auth_user->shortenlinks($this->status);
|
||||
$status_shortened = $this->status;
|
||||
|
||||
|
||||
* classes/Notice.php
|
||||
|
||||
- to _not_ shorten urls sent through api, we need to comment out this also
|
||||
|
||||
~ line 352 // if ($user) {
|
||||
// // Use the local user's shortening preferences, if applicable.
|
||||
// $final = $user->shortenLinks($content);
|
||||
// } else {
|
||||
// $final = common_shorten_links($content);
|
||||
// }
|
||||
|
106
api-changes-1.1.1/actions/apiattachment.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show a notice's attachment
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
|
||||
/**
|
||||
* Show a notice's attachment
|
||||
*
|
||||
*/
|
||||
class ApiAttachmentAction extends ApiAuthAction
|
||||
{
|
||||
const MAXCOUNT = 100;
|
||||
|
||||
var $original = null;
|
||||
var $cnt = self::MAXCOUNT;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Make a new notice for the update, save it, and show it
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$file = new File();
|
||||
$file->selectAdd(); // clears it
|
||||
$file->selectAdd('url');
|
||||
$file->id = $this->trimmed('id');
|
||||
$url = $file->fetchAll('url');
|
||||
|
||||
$file_txt = '';
|
||||
if(strstr($url[0],'.html')) {
|
||||
$file_txt['txt'] = file_get_contents(str_replace('://quitter.se','://127.0.0.1',$url[0]));
|
||||
$file_txt['body_start'] = strpos($file_txt['txt'],'<body>')+6;
|
||||
$file_txt['body_end'] = strpos($file_txt['txt'],'</body>');
|
||||
$file_txt = substr($file_txt['txt'],$file_txt['body_start'],$file_txt['body_end']-$file_txt['body_start']);
|
||||
}
|
||||
|
||||
$this->initDocument('json');
|
||||
$this->showJsonObjects($file_txt);
|
||||
$this->endDocument('json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
122
api-changes-1.1.1/actions/apicheckhub.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show a notice's attachment
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
|
||||
/**
|
||||
* Check if a url have a push-hub, i.e. if it is possible to subscribe
|
||||
*
|
||||
*/
|
||||
class ApiCheckHubAction extends ApiAuthAction
|
||||
{
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->url = urldecode($args['url']);
|
||||
|
||||
if (!$this->url) {
|
||||
$this->clientError(_('No URL.'), 403, 'json');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Validate::uri(
|
||||
$this->url, array(
|
||||
'allowed_schemes' =>
|
||||
array('http', 'https')
|
||||
)
|
||||
)) {
|
||||
$this->clientError(_('Invalid URL.'), 403, 'json');
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
|
||||
$discover = new FeedDiscovery();
|
||||
|
||||
try {
|
||||
$feeduri = $discover->discoverFromURL($this->url);
|
||||
if($feeduri) {
|
||||
$huburi = $discover->getHubLink();
|
||||
}
|
||||
} catch (FeedSubNoFeedException $e) {
|
||||
$this->clientError(_('No feed found'), 403, 'json');
|
||||
return;
|
||||
} catch (FeedSubBadResponseException $e) {
|
||||
$this->clientError(_('No hub found'), 403, 'json');
|
||||
return;
|
||||
}
|
||||
|
||||
$hub_status = array();
|
||||
if ($huburi) {
|
||||
$hub_status = array('huburi' => $huburi);
|
||||
}
|
||||
|
||||
$this->initDocument('json');
|
||||
$this->showJsonObjects($hub_status);
|
||||
$this->endDocument('json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
244
api-changes-1.1.1/actions/apiconversation.php
Normal file
|
@ -0,0 +1,244 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Show a stream of notices in a particular conversation
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Show a stream of notices in a particular conversation
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ApiconversationAction extends ApiAuthAction
|
||||
{
|
||||
protected $conversation = null;
|
||||
protected $notices = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$convId = $this->trimmed('id');
|
||||
|
||||
if (empty($convId)) {
|
||||
// TRANS: Client exception thrown when no conversation ID is given.
|
||||
throw new ClientException(_('No conversation ID.'));
|
||||
}
|
||||
|
||||
$this->conversation = Conversation::staticGet('id', $convId);
|
||||
|
||||
if (empty($this->conversation)) {
|
||||
// TRANS: Client exception thrown when referring to a non-existing conversation ID (%d).
|
||||
throw new ClientException(sprintf(_('No conversation with ID %d.'), $convId),
|
||||
404);
|
||||
}
|
||||
|
||||
// $profile = Profile::current();
|
||||
if(isset($this->auth_user)) {
|
||||
$profile = $this->auth_user->getProfile();
|
||||
}
|
||||
else {
|
||||
$profile = null;
|
||||
}
|
||||
|
||||
$stream = new ConversationNoticeStream($convId, $profile);
|
||||
|
||||
$notice = $stream->getNotices(($this->page-1) * $this->count,
|
||||
$this->count,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
|
||||
$this->notices = $notice->fetchAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($argarray=null)
|
||||
{
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Title for conversion timeline.
|
||||
$title = _m('TITLE', 'Conversation');
|
||||
$id = common_local_url('apiconversation', array('id' => $this->conversation->id, 'format' => $this->format));
|
||||
$link = common_local_url('conversation', array('id' => $this->conversation->id));
|
||||
|
||||
$self = $id;
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlTimeline($this->notices);
|
||||
break;
|
||||
case 'rss':
|
||||
$this->showRssTimeline(
|
||||
$this->notices,
|
||||
$title,
|
||||
$link,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$self
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
$atom->setUpdated('now');
|
||||
|
||||
$atom->addLink($link);
|
||||
$atom->setSelfLink($self);
|
||||
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
$this->raw($atom->getString());
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
case 'as':
|
||||
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
|
||||
$doc = new ActivityStreamJSONDocument($this->auth_user);
|
||||
$doc->setTitle($title);
|
||||
$doc->addLink($link, 'alternate', 'text/html');
|
||||
$doc->addItemsFromNotices($this->notices);
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
return strtotime($this->notices[0]->created);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
|
||||
$last = count($this->notices) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
99
api-changes-1.1.1/actions/apiexternalprofileshow.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show an external user's profile information
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
|
||||
/**
|
||||
* Ouputs information for a user, specified by ID or screen name.
|
||||
* The user's most recent status will be returned inline.
|
||||
*/
|
||||
class ApiExternalProfileShowAction extends ApiPrivateAuthAction
|
||||
{
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$profileurl = urldecode($this->arg('profileurl'));
|
||||
|
||||
$this->profile = Profile::staticGet('profileurl', $profileurl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Check the format and show the user info
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->profile)) {
|
||||
// TRANS: Client error displayed when requesting profile information for a non-existing profile.
|
||||
$this->clientError(_('Profile not found.'), 404, 'json');
|
||||
return;
|
||||
}
|
||||
|
||||
$twitter_user = $this->twitterUserArray($this->profile, true);
|
||||
|
||||
$this->initDocument('json');
|
||||
$this->showJsonObjects($twitter_user);
|
||||
$this->endDocument('json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
143
api-changes-1.1.1/actions/apisearchjson.php
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Action for showing Twitter-like JSON search results
|
||||
*
|
||||
* 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 Search
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2008-2010 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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
||||
|
||||
/**
|
||||
* Action handler for Twitter-compatible API search
|
||||
*
|
||||
* @category Search
|
||||
* @package StatusNet
|
||||
* @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/
|
||||
* @see ApiAction
|
||||
*/
|
||||
class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $query;
|
||||
var $lang;
|
||||
var $rpp;
|
||||
var $page;
|
||||
var $since_id;
|
||||
var $limit;
|
||||
var $geocode;
|
||||
|
||||
/**
|
||||
* Initialization.
|
||||
*
|
||||
* @param array $args Web and URL arguments
|
||||
*
|
||||
* @return boolean true if nothing goes wrong
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->query = $this->trimmed('q');
|
||||
$this->lang = $this->trimmed('lang');
|
||||
$this->rpp = $this->trimmed('rpp');
|
||||
|
||||
if (!$this->rpp) {
|
||||
$this->rpp = 15;
|
||||
}
|
||||
|
||||
if ($this->rpp > 100) {
|
||||
$this->rpp = 100;
|
||||
}
|
||||
|
||||
$this->page = $this->trimmed('page');
|
||||
|
||||
if (!$this->page) {
|
||||
$this->page = 1;
|
||||
}
|
||||
|
||||
// TODO: Suppport max_id -- we need to tweak the backend
|
||||
// Search classes to support it.
|
||||
|
||||
$this->since_id = $this->trimmed('since_id');
|
||||
$this->geocode = $this->trimmed('geocode');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request
|
||||
*
|
||||
* @param array $args Arguments from $_REQUEST
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show search results
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showResults()
|
||||
{
|
||||
// TODO: Support search operators like from: and to:, boolean, etc.
|
||||
|
||||
$notice = new Notice();
|
||||
|
||||
// lcase it for comparison
|
||||
$q = strtolower($this->query);
|
||||
|
||||
$this->notices = array();
|
||||
$search_engine = $notice->getSearchEngine('notice');
|
||||
$search_engine->set_sort_mode('chron');
|
||||
$search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1);
|
||||
if ($search_engine->query($q)) {
|
||||
$cnt = $notice->find();
|
||||
$this->notices = $notice->fetchAll();
|
||||
}
|
||||
|
||||
$this->showJsonTimeline($this->notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do we need to write to the database?
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
139
api-changes-1.1.1/actions/apistatusesfavs.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show up to 100 favs of a notice
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
|
||||
/**
|
||||
* Show up to 100 favs of a notice
|
||||
*
|
||||
*/
|
||||
class ApiStatusesFavsAction extends ApiAuthAction
|
||||
{
|
||||
const MAXCOUNT = 100;
|
||||
|
||||
var $original = null;
|
||||
var $cnt = self::MAXCOUNT;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$id = $this->trimmed('id');
|
||||
|
||||
$this->original = Notice::staticGet('id', $id);
|
||||
|
||||
if (empty($this->original)) {
|
||||
// TRANS: Client error displayed trying to display redents of a non-exiting notice.
|
||||
$this->clientError(_('No such notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
$cnt = $this->trimmed('count');
|
||||
|
||||
if (empty($cnt) || !is_integer($cnt)) {
|
||||
$cnt = 100;
|
||||
} else {
|
||||
$this->cnt = min((int)$cnt, self::MAXCOUNT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Get favs and return them as json object
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$fave = new Fave();
|
||||
$fave->selectAdd();
|
||||
$fave->selectAdd('user_id');
|
||||
$fave->notice_id = $this->original->id;
|
||||
$fave->orderBy('modified');
|
||||
if (!is_null($this->cnt)) {
|
||||
$fave->limit(0, $this->cnt);
|
||||
}
|
||||
|
||||
$ids = $fave->fetchAll('user_id');
|
||||
|
||||
// get nickname and profile image
|
||||
$ids_with_profile_data = array();
|
||||
$i=0;
|
||||
foreach($ids as $id) {
|
||||
$profile = Profile::staticGet('id', $id);
|
||||
$ids_with_profile_data[$i]['user_id'] = $id;
|
||||
$ids_with_profile_data[$i]['nickname'] = $profile->nickname;
|
||||
$ids_with_profile_data[$i]['fullname'] = $profile->fullname;
|
||||
$ids_with_profile_data[$i]['profileurl'] = $profile->profileurl;
|
||||
$profile = new Profile();
|
||||
$profile->id = $id;
|
||||
$avatarurl = $profile->avatarUrl(24);
|
||||
$ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
|
||||
$i++;
|
||||
}
|
||||
|
||||
$this->initDocument('json');
|
||||
$this->showJsonObjects($ids_with_profile_data);
|
||||
$this->endDocument('json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
380
api-changes-1.1.1/actions/apistatusesupdate.php
Normal file
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Post a notice (update your status) through 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
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Tom Blankenship <mac65@mac65.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how this method works. */
|
||||
|
||||
/*! @page statusesupdate statuses/update
|
||||
|
||||
@section Description
|
||||
Updates the authenticating user's status. Requires the status parameter specified below.
|
||||
Request must be a POST.
|
||||
|
||||
@par URL pattern
|
||||
/api/statuses/update.:format
|
||||
|
||||
@par Formats (:format)
|
||||
xml, json
|
||||
|
||||
@par HTTP Method(s)
|
||||
POST
|
||||
|
||||
@par Requires Authentication
|
||||
Yes
|
||||
|
||||
@param status (Required) The URL-encoded text of the status update.
|
||||
@param source (Optional) The source application name, if using HTTP authentication or an anonymous OAuth consumer.
|
||||
@param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to.
|
||||
@param lat (Optional) The latitude the status refers to.
|
||||
@param long (Optional) The longitude the status refers to.
|
||||
@param media (Optional) a media upload, such as an image or movie file.
|
||||
|
||||
@sa @ref authentication
|
||||
@sa @ref apiroot
|
||||
|
||||
@subsection usagenotes Usage notes
|
||||
|
||||
@li The URL pattern is relative to the @ref apiroot.
|
||||
@li If the @e source parameter is not supplied the source of the status will default to 'api'. When authenticated via a registered OAuth application, the application's registered name and URL will always override the source parameter.
|
||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
||||
to encode the latitude and longitude (see example response below <georss:point>).
|
||||
@li Data uploaded via the @e media parameter should be multipart/form-data encoded.
|
||||
|
||||
@subsection exampleusage Example usage
|
||||
|
||||
@verbatim
|
||||
curl -u username:password http://example.com/api/statuses/update.xml -d status='Howdy!' -d lat='30.468' -d long='-94.743'
|
||||
@endverbatim
|
||||
|
||||
@subsection exampleresponse Example response
|
||||
|
||||
@verbatim
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<status>
|
||||
<text>Howdy!</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Tue Mar 30 23:28:05 +0000 2010</created_at>
|
||||
<in_reply_to_status_id/>
|
||||
<source>api</source>
|
||||
<id>26668724</id>
|
||||
<in_reply_to_user_id/>
|
||||
<in_reply_to_screen_name/>
|
||||
<geo xmlns:georss="http://www.georss.org/georss">
|
||||
<georss:point>30.468 -94.743</georss:point>
|
||||
</geo>
|
||||
<favorited>false</favorited>
|
||||
<user>
|
||||
<id>25803</id>
|
||||
<name>Jed Sanders</name>
|
||||
<screen_name>jedsanders</screen_name>
|
||||
<location>Hoop and Holler, Texas</location>
|
||||
<description>I like to think of myself as America's Favorite.</description>
|
||||
<profile_image_url>http://avatar.example.com/25803-48-20080924200604.png</profile_image_url>
|
||||
<url>http://jedsanders.net</url>
|
||||
<protected>false</protected>
|
||||
<followers_count>5</followers_count>
|
||||
<profile_background_color/>
|
||||
<profile_text_color/>
|
||||
<profile_link_color/>
|
||||
<profile_sidebar_fill_color/>
|
||||
<profile_sidebar_border_color/>
|
||||
<friends_count>2</friends_count>
|
||||
<created_at>Wed Sep 24 20:04:00 +0000 2008</created_at>
|
||||
<favourites_count>0</favourites_count>
|
||||
<utc_offset>0</utc_offset>
|
||||
<time_zone>UTC</time_zone>
|
||||
<profile_background_image_url/>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>70</statuses_count>
|
||||
<following>true</following>
|
||||
<notifications>true</notifications>
|
||||
</user>
|
||||
</status>
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
|
||||
/**
|
||||
* Updates the authenticating user's status (posts a notice).
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Tom Blankenship <mac65@mac65.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @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 ApiStatusesUpdateAction extends ApiAuthAction
|
||||
{
|
||||
var $status = null;
|
||||
var $in_reply_to_status_id = null;
|
||||
var $lat = null;
|
||||
var $lon = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->status = $this->trimmed('status');
|
||||
$this->lat = $this->trimmed('lat');
|
||||
$this->lon = $this->trimmed('long');
|
||||
|
||||
$this->in_reply_to_status_id
|
||||
= intval($this->trimmed('in_reply_to_status_id'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Make a new notice for the update, save it, and show it
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
||||
// length > post_max_size in php.ini
|
||||
|
||||
if (empty($_FILES)
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
|
||||
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->status)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when the parameter "status" is missing.
|
||||
_('Client must provide a \'status\' parameter with a value.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->auth_user)) {
|
||||
// TRANS: Client error displayed when updating a status for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do not call shortenlinks until the whole notice has been build */
|
||||
|
||||
// Check for commands
|
||||
|
||||
$inter = new CommandInterpreter();
|
||||
$cmd = $inter->handle_command($this->auth_user, $this->status);
|
||||
|
||||
if ($cmd) {
|
||||
if ($this->supported($cmd)) {
|
||||
$cmd->execute(new Channel());
|
||||
}
|
||||
|
||||
// Cmd not supported? Twitter just returns your latest status.
|
||||
// And, it returns your last status whether the cmd was successful
|
||||
// or not!
|
||||
|
||||
$this->notice = $this->auth_user->getCurrentNotice();
|
||||
} else {
|
||||
$reply_to = null;
|
||||
|
||||
if (!empty($this->in_reply_to_status_id)) {
|
||||
// Check whether notice actually exists
|
||||
|
||||
$reply = Notice::staticGet($this->in_reply_to_status_id);
|
||||
|
||||
if ($reply) {
|
||||
$reply_to = $this->in_reply_to_status_id;
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when replying to a non-existing notice.
|
||||
_('Parent notice not found.'),
|
||||
$code = 404,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$upload = null;
|
||||
|
||||
try {
|
||||
$upload = MediaFile::fromUpload('media', $this->auth_user);
|
||||
} catch (Exception $e) {
|
||||
$this->clientError($e->getMessage(), $e->getCode(), $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($upload)) {
|
||||
$this->status .= ' ' . $upload->shortUrl();
|
||||
|
||||
/* Do not call shortenlinks until the whole notice has been build */
|
||||
}
|
||||
|
||||
/* Do call shortenlinks here & check notice length since notice is about to be saved & sent */
|
||||
//$status_shortened = $this->auth_user->shortenlinks($this->status);
|
||||
|
||||
/* DO NOT! */
|
||||
$status_shortened = $this->status;
|
||||
|
||||
if (Notice::contentTooLong($status_shortened)) {
|
||||
if (isset($upload)) {
|
||||
$upload->delete();
|
||||
}
|
||||
// TRANS: Client error displayed exceeding the maximum notice length.
|
||||
// TRANS: %d is the maximum lenth for a notice.
|
||||
$msg = _m('Maximum notice size is %d character, including attachment URL.',
|
||||
'Maximum notice size is %d characters, including attachment URL.',
|
||||
Notice::maxContent());
|
||||
/* Use HTTP 413 error code (Request Entity Too Large)
|
||||
* instead of basic 400 for better understanding
|
||||
*/
|
||||
$this->clientError(sprintf($msg, Notice::maxContent()),
|
||||
413,
|
||||
$this->format);
|
||||
}
|
||||
|
||||
|
||||
$content = html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8');
|
||||
|
||||
$options = array('reply_to' => $reply_to);
|
||||
|
||||
if ($this->auth_user->shareLocation()) {
|
||||
|
||||
$locOptions = Notice::locationOptions($this->lat,
|
||||
$this->lon,
|
||||
null,
|
||||
null,
|
||||
$this->auth_user->getProfile());
|
||||
|
||||
$options = array_merge($options, $locOptions);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->notice = Notice::saveNew(
|
||||
$this->auth_user->id,
|
||||
$content,
|
||||
$this->source,
|
||||
$options
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this->clientError($e->getMessage(), $e->getCode(), $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($upload)) {
|
||||
$upload->attachToNotice($this->notice);
|
||||
}
|
||||
}
|
||||
|
||||
$this->showNotice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the resulting notice
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showNotice()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
if ($this->format == 'xml') {
|
||||
$this->showSingleXmlStatus($this->notice);
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->show_single_json_status($this->notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this command supported when doing an update from the API?
|
||||
*
|
||||
* @param string $cmd the command to check for
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
function supported($cmd)
|
||||
{
|
||||
static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
|
||||
'FavCommand', 'OnCommand', 'OffCommand', 'JoinCommand', 'LeaveCommand');
|
||||
|
||||
if (in_array(get_class($cmd), $cmdlist)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
248
api-changes-1.1.1/actions/apitimelinetag.php
Normal file
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show the latest notices for a given tag
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @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>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
|
||||
/**
|
||||
* Returns the 20 most recent notices tagged by a given tag
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @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 ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
common_debug("apitimelinetag prepare()");
|
||||
|
||||
$this->tag = $this->arg('tag');
|
||||
$this->notices = $this->getNotices();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Just show the notices
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showTimeline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the timeline of notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showTimeline()
|
||||
{
|
||||
$sitename = common_config('site', 'name');
|
||||
$sitelogo = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
|
||||
// TRANS: Title for timeline with lastest notices with a given tag.
|
||||
// TRANS: %s is the tag.
|
||||
$title = sprintf(_("Notices tagged with %s"), $this->tag);
|
||||
$subtitle = sprintf(
|
||||
// TRANS: Subtitle for timeline with lastest notices with a given tag.
|
||||
// TRANS: %1$s is the tag, $2$s is the StatusNet sitename.
|
||||
_('Updates tagged with %1$s on %2$s!'),
|
||||
$this->tag,
|
||||
$sitename
|
||||
);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:TagTimeline:".$this->tag;
|
||||
|
||||
$link = common_local_url(
|
||||
'tag',
|
||||
array('tag' => $this->tag)
|
||||
);
|
||||
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlTimeline($this->notices);
|
||||
break;
|
||||
case 'rss':
|
||||
$this->showRssTimeline(
|
||||
$this->notices,
|
||||
$title,
|
||||
$link,
|
||||
$subtitle,
|
||||
null,
|
||||
$sitelogo,
|
||||
$self
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
$atom->setSubtitle($subtitle);
|
||||
$atom->setLogo($logo);
|
||||
$atom->setUpdated('now');
|
||||
|
||||
$atom->addLink($link);
|
||||
$atom->setSelfLink($self);
|
||||
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
$this->raw($atom->getString());
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
case 'as':
|
||||
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
|
||||
$doc = new ActivityStreamJSONDocument($this->auth_user);
|
||||
$doc->setTitle($title);
|
||||
$doc->addLink($link, 'alternate', 'text/html');
|
||||
$doc->addItemsFromNotices($this->notices);
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notices
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
|
||||
$notice = Notice_tag::getStream(
|
||||
$this->tag,
|
||||
($this->page - 1) * $this->count,
|
||||
$this->count + 1,
|
||||
$this->since_id,
|
||||
$this->max_id
|
||||
);
|
||||
|
||||
while ($notice->fetch()) {
|
||||
$notices[] = clone($notice);
|
||||
}
|
||||
|
||||
return $notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this action read only?
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this feed last modified?
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
return strtotime($this->notices[0]->created);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity tag for this stream
|
||||
*
|
||||
* Returns an Etag based on the action name, language, and
|
||||
* timestamps of the first and last notice in the timeline
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
|
||||
$last = count($this->notices) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->tag,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
524
api-changes-1.1.1/actions/apitimelineuser.php
Normal file
|
@ -0,0 +1,524 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author mac65 <mac65@mac65.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
|
||||
/**
|
||||
* Returns the most recent notices (default 20) posted by the authenticating
|
||||
* user. Another user's timeline can be requested via the id parameter. This
|
||||
* is the API equivalent of the user profile web page.
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author mac65 <mac65@mac65.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @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 ApiTimelineUserAction extends ApiBareAuthAction
|
||||
{
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed requesting most recent notices for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->notices = $this->getNotices();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Just show the notices
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($this->isPost()) {
|
||||
$this->handlePost();
|
||||
} else {
|
||||
$this->showTimeline();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the timeline of notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
// We'll use the shared params from the Atom stub
|
||||
// for other feed types.
|
||||
$atom = new AtomUserNoticeFeed($this->user, $this->auth_user);
|
||||
|
||||
$link = common_local_url(
|
||||
'showstream',
|
||||
array('nickname' => $this->user->nickname)
|
||||
);
|
||||
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
// FriendFeed's SUP protocol
|
||||
// Also added RSS and Atom feeds
|
||||
|
||||
$suplink = common_local_url('sup', null, null, $this->user->id);
|
||||
header('X-SUP-ID: ' . $suplink);
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlTimeline($this->notices);
|
||||
break;
|
||||
case 'rss':
|
||||
$this->showRssTimeline(
|
||||
$this->notices,
|
||||
$atom->title,
|
||||
$link,
|
||||
$atom->subtitle,
|
||||
$suplink,
|
||||
$atom->logo,
|
||||
$self
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom->setId($self);
|
||||
$atom->setSelfLink($self);
|
||||
|
||||
// Add navigation links: next, prev, first
|
||||
// Note: we use IDs rather than pages for navigation; page boundaries
|
||||
// change too quickly!
|
||||
|
||||
if (!empty($this->next_id)) {
|
||||
$nextUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id),
|
||||
array('max_id' => $this->next_id));
|
||||
|
||||
$atom->addLink($nextUrl,
|
||||
array('rel' => 'next',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) {
|
||||
|
||||
$lastNotice = $this->notices[0];
|
||||
$lastId = $lastNotice->id;
|
||||
|
||||
$prevUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id),
|
||||
array('since_id' => $lastId));
|
||||
|
||||
$atom->addLink($prevUrl,
|
||||
array('rel' => 'prev',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) {
|
||||
|
||||
$firstUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id));
|
||||
|
||||
$atom->addLink($firstUrl,
|
||||
array('rel' => 'first',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
}
|
||||
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
$this->raw($atom->getString());
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
case 'as':
|
||||
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
|
||||
$doc = new ActivityStreamJSONDocument($this->auth_user);
|
||||
$doc->setTitle($atom->title);
|
||||
$doc->addLink($link, 'alternate', 'text/html');
|
||||
$doc->addItemsFromNotices($this->notices);
|
||||
|
||||
// XXX: Add paging extension?
|
||||
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notices
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
|
||||
$user_profile = $this->user->getProfile();
|
||||
if(isset($this->auth_user)) {
|
||||
$auth_user_profile = $this->auth_user->getProfile();
|
||||
}
|
||||
else {
|
||||
$auth_user_profile = null;
|
||||
}
|
||||
|
||||
$stream = new ProfileNoticeStream($user_profile, $auth_user_profile);
|
||||
|
||||
$notice = $stream->getNotices(($this->page-1) * $this->count,
|
||||
$this->count + 1,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
|
||||
while ($notice->fetch()) {
|
||||
if (count($notices) < $this->count) {
|
||||
$notices[] = clone($notice);
|
||||
} else {
|
||||
$this->next_id = $notice->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* We expose AtomPub here, so non-GET/HEAD reqs must be read/write.
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this feed last modified?
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
return strtotime($this->notices[0]->created);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity tag for this stream
|
||||
*
|
||||
* Returns an Etag based on the action name, language, user ID, and
|
||||
* timestamps of the first and last notice in the timeline
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
$last = count($this->notices) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->user->id) {
|
||||
// TRANS: Client error displayed trying to add a notice to another user's timeline.
|
||||
$this->clientError(_('Only the user can add to their own timeline.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Only handle posts for Atom
|
||||
if ($this->format != 'atom') {
|
||||
// TRANS: Client error displayed when using another format than AtomPub.
|
||||
$this->clientError(_('Only accept AtomPub for Atom feeds.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$xml = trim(file_get_contents('php://input'));
|
||||
if (empty($xml)) {
|
||||
// TRANS: Client error displayed attempting to post an empty API notice.
|
||||
$this->clientError(_('Atom post must not be empty.'));
|
||||
}
|
||||
|
||||
$old = error_reporting(error_reporting() & ~(E_WARNING | E_NOTICE));
|
||||
$dom = new DOMDocument();
|
||||
$ok = $dom->loadXML($xml);
|
||||
error_reporting($old);
|
||||
if (!$ok) {
|
||||
// TRANS: Client error displayed attempting to post an API that is not well-formed XML.
|
||||
$this->clientError(_('Atom post must be well-formed XML.'));
|
||||
}
|
||||
|
||||
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
|
||||
$dom->documentElement->localName != 'entry') {
|
||||
// TRANS: Client error displayed when not using an Atom entry.
|
||||
$this->clientError(_('Atom post must be an Atom entry.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
$saved = null;
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity, $this->user, &$saved))) {
|
||||
if ($activity->verb != ActivityVerb::POST) {
|
||||
// TRANS: Client error displayed when not using the POST verb. Do not translate POST.
|
||||
$this->clientError(_('Can only handle POST activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$note = $activity->objects[0];
|
||||
|
||||
if (!in_array($note->type, array(ActivityObject::NOTE,
|
||||
ActivityObject::BLOGENTRY,
|
||||
ActivityObject::STATUS))) {
|
||||
// TRANS: Client error displayed when using an unsupported activity object type.
|
||||
// TRANS: %s is the unsupported activity object type.
|
||||
$this->clientError(sprintf(_('Cannot handle activity object type "%s".'),
|
||||
$note->type));
|
||||
return;
|
||||
}
|
||||
|
||||
$saved = $this->postNote($activity);
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $this->user, $saved));
|
||||
}
|
||||
|
||||
if (!empty($saved)) {
|
||||
header('HTTP/1.1 201 Created');
|
||||
header("Location: " . common_local_url('ApiStatusesShow', array('id' => $saved->id,
|
||||
'format' => 'atom')));
|
||||
$this->showSingleAtomStatus($saved);
|
||||
}
|
||||
}
|
||||
|
||||
function postNote($activity)
|
||||
{
|
||||
$note = $activity->objects[0];
|
||||
|
||||
// Use summary as fallback for content
|
||||
|
||||
if (!empty($note->content)) {
|
||||
$sourceContent = $note->content;
|
||||
} else if (!empty($note->summary)) {
|
||||
$sourceContent = $note->summary;
|
||||
} else if (!empty($note->title)) {
|
||||
$sourceContent = $note->title;
|
||||
} else {
|
||||
// @fixme fetch from $sourceUrl?
|
||||
// TRANS: Client error displayed when posting a notice without content through the API.
|
||||
// TRANS: %d is the notice ID (number).
|
||||
$this->clientError(sprintf(_('No content for notice %d.'),
|
||||
$note->id));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$content = html_entity_decode(strip_tags($rendered), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$shortened = $this->auth_user->shortenLinks($content);
|
||||
|
||||
$options = array('is_local' => Notice::LOCAL_PUBLIC,
|
||||
'rendered' => $rendered,
|
||||
'replies' => array(),
|
||||
'groups' => array(),
|
||||
'tags' => array(),
|
||||
'urls' => array());
|
||||
|
||||
// accept remote URI (not necessarily a good idea)
|
||||
|
||||
common_debug("Note ID is {$note->id}");
|
||||
|
||||
if (!empty($note->id)) {
|
||||
$notice = Notice::staticGet('uri', trim($note->id));
|
||||
|
||||
if (!empty($notice)) {
|
||||
// TRANS: Client error displayed when using another format than AtomPub.
|
||||
// TRANS: %s is the notice URI.
|
||||
$this->clientError(sprintf(_('Notice with URI "%s" already exists.'),
|
||||
$note->id));
|
||||
return;
|
||||
}
|
||||
common_log(LOG_NOTICE, "Saving client-supplied notice URI '$note->id'");
|
||||
$options['uri'] = $note->id;
|
||||
}
|
||||
|
||||
// accept remote create time (also maybe not such a good idea)
|
||||
|
||||
if (!empty($activity->time)) {
|
||||
common_log(LOG_NOTICE, "Saving client-supplied create time {$activity->time}");
|
||||
$options['created'] = common_sql_date($activity->time);
|
||||
}
|
||||
|
||||
// Check for optional attributes...
|
||||
|
||||
if (!empty($activity->context)) {
|
||||
|
||||
foreach ($activity->context->attention as $uri) {
|
||||
|
||||
$profile = Profile::fromURI($uri);
|
||||
|
||||
if (!empty($profile)) {
|
||||
$options['replies'][] = $uri;
|
||||
} else {
|
||||
$group = User_group::staticGet('uri', $uri);
|
||||
if (!empty($group)) {
|
||||
$options['groups'][] = $group->id;
|
||||
} else {
|
||||
// @fixme: hook for discovery here
|
||||
common_log(LOG_WARNING, sprintf('AtomPub post with unknown attention URI %s', $uri));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain direct reply associations
|
||||
// @fixme what about conversation ID?
|
||||
|
||||
if (!empty($activity->context->replyToID)) {
|
||||
$orig = Notice::staticGet('uri',
|
||||
$activity->context->replyToID);
|
||||
if (!empty($orig)) {
|
||||
$options['reply_to'] = $orig->id;
|
||||
}
|
||||
}
|
||||
|
||||
$location = $activity->context->location;
|
||||
|
||||
if ($location) {
|
||||
$options['lat'] = $location->lat;
|
||||
$options['lon'] = $location->lon;
|
||||
if ($location->location_id) {
|
||||
$options['location_ns'] = $location->location_ns;
|
||||
$options['location_id'] = $location->location_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Atom categories <-> hashtags
|
||||
|
||||
foreach ($activity->categories as $cat) {
|
||||
if ($cat->term) {
|
||||
$term = common_canonical_tag($cat->term);
|
||||
if ($term) {
|
||||
$options['tags'][] = $term;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Atom enclosures -> attachment URLs
|
||||
foreach ($activity->enclosures as $href) {
|
||||
// @fixme save these locally or....?
|
||||
$options['urls'][] = $href;
|
||||
}
|
||||
|
||||
$saved = Notice::saveNew($this->user->id,
|
||||
$content,
|
||||
'atompub', // TODO: deal with this
|
||||
$options);
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
function purify($content)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
return htmLawed($content, $config);
|
||||
}
|
||||
}
|
2761
api-changes-1.1.1/classes/Notice.php
Normal file
1684
api-changes-1.1.1/lib/apiaction.php
Normal file
1193
api-changes-1.1.1/lib/router.php
Normal file
BIN
favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
img/birds.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
img/birds_rtl.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
img/button_birds.png
Normal file
After Width: | Height: | Size: 736 B |
BIN
img/ekan4.jpg
Normal file
After Width: | Height: | Size: 268 KiB |
BIN
img/logo.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
img/sprite.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
img/sprite_bgs.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
176
index.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php include 'settings.php'; ?><!--
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
|
||||
--><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><?php print $sitetitle; ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="<?php print $qvitterpath; ?>css/1.css" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<?php print $qvitterpath; ?>favicon.ico">
|
||||
<script>
|
||||
window.timeBetweenPolling = <?php print $timebetweenpolling; ?>;
|
||||
window.fullUrlToThisQvitterApp = '<?php print $qvitterpath; ?>';
|
||||
window.siteRootDomain = '<?php print $siterootdomain; ?>';
|
||||
window.useHistoryPushState = <?php if($usehistorypushstate) print 'true'; else print 'false'; ?>;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="topbar">
|
||||
<a id="logolink">
|
||||
<div id="logo"></div>
|
||||
<div class="dropdown-toggle">
|
||||
<i class="nav-session"></i>
|
||||
<b class="caret"></b>
|
||||
</div>
|
||||
</a>
|
||||
<ul class="quitter-settings dropdown-menu">
|
||||
<li class="dropdown-caret right">
|
||||
<span class="caret-outer"></span>
|
||||
<span class="caret-inner"></span>
|
||||
</li>
|
||||
<li><a id="logout"></a></li>
|
||||
</ul>
|
||||
<img id="birds-top" src="<?php print $qvitterpath; ?>img/birds.png" />
|
||||
<div class="global-nav">
|
||||
<div class="global-nav-inner">
|
||||
<div class="container">
|
||||
<div id="search">
|
||||
<input type="text" spellcheck="false" autocomplete="off" name="q" placeholder="Sök" id="search-query" class="search-input">
|
||||
<span class="search-icon">
|
||||
<button class="icon nav-search" type="submit" tabindex="-1">
|
||||
<span> Sök </span>
|
||||
</button>
|
||||
</span>
|
||||
<input type="text" spellcheck="false" autocomplete="off" id="search-query-hint" class="search-input search-hinting-input" disabled="disabled">
|
||||
</div>
|
||||
<ul class="language-dropdown">
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle">
|
||||
<small></small>
|
||||
<span class="current-language"></span>
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-caret right">
|
||||
<span class="caret-outer"></span>
|
||||
<span class="caret-inner"></span>
|
||||
</li>
|
||||
<li><a class="language-link" title="Arabic" data-lang-code="ar">العربيّة</a></li>
|
||||
<li><a class="language-link" title="German" data-lang-code="de">Deutsch</a></li>
|
||||
<li><a class="language-link" title="English" data-lang-code="en">English</a></li>
|
||||
<li><a class="language-link" title="Spanish" data-lang-code="es">Español</a></li>
|
||||
<li><a class="language-link" title="Farsi" data-lang-code="fa">فارسی</a></li>
|
||||
<li><a class="language-link" title="French" data-lang-code="fr">français</a></li>
|
||||
<li><a class="language-link" title="Swedish" data-lang-code="sv">svenska</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page-container">
|
||||
<div id="user-container" style="display:none;">
|
||||
<div id="login-content">
|
||||
<div id="username-container">
|
||||
<input id="username" type="text" value="" tabindex="1" />
|
||||
</div>
|
||||
<table class="password-signin"><tbody><tr>
|
||||
<td class="flex-table-primary">
|
||||
<div class="placeholding-input">
|
||||
<input id="password" type="password" tabindex="2" value="" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="flex-table-secondary">
|
||||
<button class="submit" type="submit" id="submit-login" tabindex="4"></button>
|
||||
</td>
|
||||
</tr></tbody></table>
|
||||
<div id="remember-forgot">
|
||||
<input type="checkbox" id="rememberme" name="rememberme" value="yes" tabindex="3"> <span id="rememberme_label"></span> · <a href="http://quitter.se/main/recoverpassword"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="user-header">
|
||||
<img id="user-avatar" src="" />
|
||||
<div id="user-name"></div>
|
||||
<div id="user-screen-name"></div>
|
||||
<div id="user-profile-link"></div>
|
||||
</div>
|
||||
<div id="user-body">
|
||||
<a><div id="user-queets"><strong></strong><div class="label"></div></div></a>
|
||||
<a><div id="user-following"><strong></strong><div class="label"></div></div></a>
|
||||
<a><div id="user-followers"><strong></strong><div class="label"></div></div></a>
|
||||
<a><div id="user-groups"><strong></strong><div class="label"></div></div></a>
|
||||
</div>
|
||||
<div id="user-footer">
|
||||
<div id="queet-box" class="queet-box"></div>
|
||||
<div id="queet-toolbar">
|
||||
<div id="queet-box-extras"></div>
|
||||
<div id="queet-button">
|
||||
<span id="queet-counter"></span>
|
||||
<button id="queet"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-container">
|
||||
<div class="stream-selection" data-stream-header="" data-stream-name="statuses/friends_timeline.json"><i class="chev-right"></i></div>
|
||||
<div class="stream-selection" data-stream-header="" data-stream-name="statuses/mentions.json"><i class="chev-right"></i></div>
|
||||
<div class="stream-selection" data-stream-header="" data-stream-name="favorites.json"><i class="chev-right"></i></div>
|
||||
<div class="stream-selection" data-stream-header="" data-stream-name="statuses/public_timeline.json"><i class="chev-right"></i></div>
|
||||
</div>
|
||||
<div class="menu-container" id="history-container"></div>
|
||||
</div>
|
||||
<div id="feed">
|
||||
<div id="feed-header">
|
||||
<div id="feed-header-inner">
|
||||
<h2></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stream-item hidden"><div id="new-queets-bar"></div></div>
|
||||
<div id="feed-body"></div>
|
||||
</div>
|
||||
|
||||
<div id="footer"></div>
|
||||
</div>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/jquery-2.0.2.min.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/jquery-ui-1.10.3.min.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/jquery.easing.1.3.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/dom-functions-1.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/misc-functions-1.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/ajax-functions-1.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/qvitter-1.js"></script>
|
||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lan-1.js"></script>
|
||||
</body>
|
||||
</html>
|
397
js/ajax-functions-1.js
Normal file
|
@ -0,0 +1,397 @@
|
|||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Check login credentials with http basic auth
|
||||
·
|
||||
· @param username: users screen name
|
||||
· @param password: users password
|
||||
· @param actionOnSuccess: callback function on log in success
|
||||
·
|
||||
· · · · · · · · · */
|
||||
|
||||
function checkLogin(username,password,actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
getRequest: "account/verify_credentials.json",
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if(typeof data.error == 'undefined') {
|
||||
actionOnSuccess(data);
|
||||
}
|
||||
else {
|
||||
alert(data.error);
|
||||
remove_spinner();
|
||||
$('#submit-login').removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Generic API GET request
|
||||
·
|
||||
· @param stream: any api get-request e.g. 'statuses/favs/111111.json'
|
||||
· @param actionOnSuccess: callback function
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function getFromAPI(stream, actionOnSuccess) {
|
||||
|
||||
// request without username/password
|
||||
if(typeof window.loginUsername == 'undefined') {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
getRequest: stream
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
actionOnSuccess(data);
|
||||
},
|
||||
error: function(data) {
|
||||
actionOnSuccess(false);
|
||||
console.log(data);
|
||||
remove_spinner();
|
||||
}
|
||||
});
|
||||
}
|
||||
// with username/password if set
|
||||
else {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
getRequest: stream,
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
actionOnSuccess(data);
|
||||
},
|
||||
error: function(data) {
|
||||
actionOnSuccess(false);
|
||||
console.log(data);
|
||||
remove_spinner();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Post queet
|
||||
·
|
||||
· @param queetText_txt: the text to post
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function postQueetToAPI(queetText_txt, actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: 'statuses/update.json',
|
||||
status: queetText_txt,
|
||||
source: 'Qvitter',
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType: "json",
|
||||
error: function(data){ actionOnSuccess(false); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Post follow or unfollow user request
|
||||
·
|
||||
· @param followOrUnfollow: either 'follow' or 'unfollow'
|
||||
· @param user_id: the user id of the user we want to follow
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function APIFollowOrUnfollowUser(followOrUnfollow,user_id,this_element,actionOnSuccess) {
|
||||
|
||||
if(followOrUnfollow == 'follow') {
|
||||
var postRequest = 'friendships/create.json';
|
||||
}
|
||||
else if (followOrUnfollow == 'unfollow') {
|
||||
var postRequest = 'friendships/destroy.json';
|
||||
}
|
||||
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: postRequest,
|
||||
user_id: user_id,
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType:"json",
|
||||
error: function(data){ actionOnSuccess(false,this_element); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data,this_element);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Post join or leave group request
|
||||
·
|
||||
· @param joinOrLeave: either 'join' or 'leave'
|
||||
· @param group_id: group's id
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function APIJoinOrLeaveGroup(joinOrLeave,group_id,this_element,actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: 'statusnet/groups/' + joinOrLeave + '.json',
|
||||
id: group_id,
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType:"json",
|
||||
error: function(data){ actionOnSuccess(false,this_element); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data,this_element);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Post reply
|
||||
·
|
||||
· @param queetText_txt: the text to post
|
||||
· @param in_reply_to_status_id: the local id for the queet to reply to
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function postReplyToAPI(queetText_txt, in_reply_to_status_id, actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: 'statuses/update.json',
|
||||
status: queetText_txt,
|
||||
source: 'Qvitter',
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword,
|
||||
in_reply_to_status_id: in_reply_to_status_id
|
||||
},
|
||||
dataType:"json",
|
||||
error: function(data){ actionOnSuccess(false); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Generic POST-action
|
||||
·
|
||||
· @param action: the api action, e.q. 'statuses/retweet/1.json'
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function postActionToAPI(action, actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: action,
|
||||
source: 'Qvitter',
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType:"json",
|
||||
error: function(data){ actionOnSuccess(false); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Generic POST-action
|
||||
·
|
||||
· @param action: the api action, e.q. 'statuses/retweet/1.json'
|
||||
· @param actionOnSuccess: callback function, false on error, data on success
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function postActionToAPI(action, actionOnSuccess) {
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
postRequest: action,
|
||||
source: 'Qvitter',
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType:"json",
|
||||
error: function(data){ actionOnSuccess(false); console.log(data); },
|
||||
success: function(data) { actionOnSuccess(data);}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Delete requeet
|
||||
·
|
||||
· @param this_stream_item: jQuery object for stream-item
|
||||
· @param this_action: JQuery object for the requeet-button
|
||||
· @param my_rq_id: the id for the requeet
|
||||
·
|
||||
· · · · · · · · · */
|
||||
|
||||
function unRequeet(this_stream_item, this_action, my_rq_id) {
|
||||
this_action.children('.with-icn').removeClass('done');
|
||||
this_action.find('.with-icn b').html(window.sL.requeetVerb);
|
||||
this_stream_item.removeClass('requeeted');
|
||||
|
||||
// post unrequeet
|
||||
postActionToAPI('statuses/destroy/' + my_rq_id + '.json', function(data) {
|
||||
if(data) {
|
||||
remove_spinner();
|
||||
this_stream_item.removeAttr('data-requeeted-by-me-id');
|
||||
}
|
||||
else {
|
||||
remove_spinner();
|
||||
this_action.children('.with-icn').addClass('done');
|
||||
this_action.find('.with-icn b').html(window.sL.requeetedVerb);
|
||||
this_stream_item.addClass('requeeted');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Gets favs or requeets for a queet from api
|
||||
·
|
||||
· @param apiaction: i.e. 'favs' or 'requeets'
|
||||
· @param qid: the queet id
|
||||
· @param actionOnSuccess: callback function
|
||||
·
|
||||
· · · · · · · · · */
|
||||
|
||||
function getFavsOrRequeetsForQueet(apiaction,qid,actionOnSuccess) {
|
||||
if(apiaction=="requeets") { apiaction="retweets"; } // we might mix this up...
|
||||
$.ajax({ url: window.fullUrlToThisQvitterApp + 'API.php',
|
||||
type: "POST",
|
||||
data: {
|
||||
getRequest: "statuses/" + apiaction + "/" + qid + ".json",
|
||||
username: window.loginUsername,
|
||||
password: window.loginPassword
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if(data.length > 0) {
|
||||
actionOnSuccess(data);
|
||||
}
|
||||
else {
|
||||
actionOnSuccess(false);
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
remove_spinner();
|
||||
console.log(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Shorten urls in box
|
||||
·
|
||||
· @param apiaction: i.e. 'favs' or 'requeets'
|
||||
· @param qid: the queet id
|
||||
· @param actionOnSuccess: callback function
|
||||
·
|
||||
· params included to pass along to countCharsInQueetBox
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function shortenUrlsInBox(box,cnt,btn) {
|
||||
// wrap urls
|
||||
// var allurls = findUrls(box.html().replace(/&/gi,'&').replace(/ /gi,' '));
|
||||
// $.each(allurls,function(key,obj){
|
||||
// if(obj.substring(0,15) != 'http://qttr.at/' && obj.length > 20) { // don't shorten if link is qttr.at or very short already
|
||||
// box.html(box.html().replace(/&/gi,'&').replace(obj,'<a class="shortening">' + obj + '</a>'));
|
||||
// placeCaretAtEnd(document.getElementById(box.attr('id')));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // shorten urls vith qttr.at
|
||||
// $.each(box.find('a.shortening'),function(key,obj){
|
||||
// display_spinner();
|
||||
// var urlEncodedUrl = encodeURIComponent($(obj).html().replace(/&/gi,'&'));
|
||||
// $.ajax({ url: "http://qttr.at/yourls-api.php?format=jsonp&action=shorturl&signature=b6afeec983&url=" + urlEncodedUrl, type: "GET", dataType: "jsonp", success: function(data) {
|
||||
// if(typeof data.shorturl != 'undefined') {
|
||||
// $(obj).before(data.shorturl);
|
||||
// }
|
||||
// else {
|
||||
// $(obj).before($(obj).html());
|
||||
// }
|
||||
// $(obj).remove();
|
||||
// remove_spinner();
|
||||
// placeCaretAtEnd(document.getElementById(box.attr('id')));
|
||||
// countCharsInQueetBox(box,cnt,btn);
|
||||
// }});
|
||||
// });
|
||||
}
|
||||
|
1381
js/dom-functions-1.js
Normal file
6
js/jquery-2.0.2.min.js
vendored
Normal file
12
js/jquery-ui-1.10.3.min.js
vendored
Normal file
205
js/jquery.easing.1.3.js
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
jQuery.easing['jswing'] = jQuery.easing['swing'];
|
||||
|
||||
jQuery.extend( jQuery.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert(jQuery.easing.default);
|
||||
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
703
js/lan-1.js
Normal file
|
@ -0,0 +1,703 @@
|
|||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
// langages object
|
||||
window.l = new Object();
|
||||
|
||||
|
||||
// spanish
|
||||
window.l.es = new Object();
|
||||
window.l.es.languageName = 'Español';
|
||||
window.l.es.loginUsername = 'Nombre de usuario o correo electrónico';
|
||||
window.l.es.loginPassword = 'Contraseña';
|
||||
window.l.es.loginSignIn = 'Iniciar sesión';
|
||||
window.l.es.loginRememberMe = 'Recordar mis datos';
|
||||
window.l.es.loginForgotPassword = '¿Olvidaste tu contraseña?';
|
||||
window.l.es.notices = 'Queets';
|
||||
window.l.es.followers = 'Seguidores';
|
||||
window.l.es.following = 'Siguiendo';
|
||||
window.l.es.groups = 'Grupos';
|
||||
window.l.es.compose = 'Publicar un nuevo Queet...';
|
||||
window.l.es.queetVerb = 'Quittear';
|
||||
window.l.es.queetsNounPlural = 'Queets';
|
||||
window.l.es.logout = 'Cerrar sesión';
|
||||
window.l.es.languageSelected = 'Idioma:';
|
||||
window.l.es.viewMyProfilePage = 'Ver mi página de perfil';
|
||||
window.l.es.expand = 'Abrir';
|
||||
window.l.es.collapse = 'Reducir';
|
||||
window.l.es.details = 'Detalles';
|
||||
window.l.es.expandFullConversation = 'Ver la conversación entera';
|
||||
window.l.es.replyVerb = 'Responder';
|
||||
window.l.es.requeetVerb = 'Requittear';
|
||||
window.l.es.favoriteVerb = 'Favorito';
|
||||
window.l.es.requeetedVerb = 'Requitteado';
|
||||
window.l.es.favoritedVerb = 'Favorito';
|
||||
window.l.es.replyTo = 'Responder a';
|
||||
window.l.es.requeetedBy = 'Requitteado por';
|
||||
window.l.es.favoriteNoun = 'Favorito';
|
||||
window.l.es.favoritesNoun = 'Favoritos';
|
||||
window.l.es.requeetNoun = 'Requeet';
|
||||
window.l.es.requeetsNoun = 'Requeets';
|
||||
window.l.es.newQueet = 'nuevo Queet';
|
||||
window.l.es.newQueets = 'nuevos Queets';
|
||||
window.l.es.longmonthsJanuary = "enero";
|
||||
window.l.es.longmonthsFebruary = "febrero";
|
||||
window.l.es.longmonthsMars = "marzo";
|
||||
window.l.es.longmonthsApril = "abril";
|
||||
window.l.es.longmonthsMay = "mayo";
|
||||
window.l.es.longmonthsJune = "junio";
|
||||
window.l.es.longmonthsJuly = "julio";
|
||||
window.l.es.longmonthsAugust = "agosto";
|
||||
window.l.es.longmonthsSeptember = "septiembre";
|
||||
window.l.es.longmonthsOctober = "octubre";
|
||||
window.l.es.longmonthsNovember = "noviembre";
|
||||
window.l.es.longmonthsDecember = "diciembre";
|
||||
window.l.es.shortmonthsJanuary = "enero";
|
||||
window.l.es.shortmonthsFebruary = "feb";
|
||||
window.l.es.shortmonthsMars = "marzo";
|
||||
window.l.es.shortmonthsApril = "abr";
|
||||
window.l.es.shortmonthsMay = "mayo";
|
||||
window.l.es.shortmonthsJune = "jun";
|
||||
window.l.es.shortmonthsJuly = "jul";
|
||||
window.l.es.shortmonthsAugust = "agosto";
|
||||
window.l.es.shortmonthsSeptember = "sept";
|
||||
window.l.es.shortmonthsOctober = "oct";
|
||||
window.l.es.shortmonthsNovember = "nov";
|
||||
window.l.es.shortmonthsDecember = "dic";
|
||||
window.l.es.time12am = '{time} AM';
|
||||
window.l.es.time12pm = '{time} PM';
|
||||
window.l.es.longDateFormat = '{time24} - {day} {month} {year}';
|
||||
window.l.es.shortDateFormatSeconds = '{seconds}s';
|
||||
window.l.es.shortDateFormatMinutes = '{minutes}min';
|
||||
window.l.es.shortDateFormatHours = '{hours}h';
|
||||
window.l.es.shortDateFormatDate = '{day} {month}';
|
||||
window.l.es.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.es.now = 'ahorita';
|
||||
window.l.es.posting = 'enviando';
|
||||
window.l.es.viewMoreInConvBefore = '← Ver más en la conversación';
|
||||
window.l.es.viewMoreInConvAfter = 'Ver más en la conversación →';
|
||||
window.l.es.mentions = 'Menciones';
|
||||
window.l.es.publicTimeline = 'Línea temporal pública';
|
||||
window.l.es.searchVerb = 'Buscar';
|
||||
window.l.es.deleteVerb = 'Eliminar';
|
||||
window.l.es.cancelVerb = 'Cancelar';
|
||||
window.l.es.deleteConfirmation = '¿Estás seguro de que quieres eliminar este queet?';
|
||||
window.l.es.userFollow = 'Seguir';
|
||||
window.l.es.userFollowing = 'Siguiendo';
|
||||
window.l.es.userUnfollow = 'Dejar de seguir';
|
||||
window.l.es.joinGroup = 'Unirse al grupo';
|
||||
window.l.es.isMemberOfGroup = 'Abandonar grupo';
|
||||
window.l.es.leaveGroup = 'Abandonar grupo';
|
||||
window.l.es.memberCount = 'Miembros';
|
||||
window.l.es.adminCount = 'Administradores';
|
||||
|
||||
|
||||
// french
|
||||
window.l.fr = new Object();
|
||||
window.l.fr.languageName = 'français';
|
||||
window.l.fr.loginUsername = 'Nom d\'utilisateur ou email';
|
||||
window.l.fr.loginPassword = 'Mot de passe';
|
||||
window.l.fr.loginSignIn = 'Se connecter';
|
||||
window.l.fr.loginRememberMe = 'Se souvenir de moi';
|
||||
window.l.fr.loginForgotPassword = 'Mot de passe oublié ?';
|
||||
window.l.fr.notices = 'Queets';
|
||||
window.l.fr.followers = 'Abonnés';
|
||||
window.l.fr.following = 'Abonnements';
|
||||
window.l.fr.groups = 'Groupes';
|
||||
window.l.fr.compose = 'Écrire un nouveau Queet...';
|
||||
window.l.fr.queetVerb = 'Queeter';
|
||||
window.l.fr.queetsNounPlural = 'Queets';
|
||||
window.l.fr.logout = 'Déconnexion';
|
||||
window.l.fr.languageSelected = 'Langue :';
|
||||
window.l.fr.viewMyProfilePage = 'Voir ma page de profil';
|
||||
window.l.fr.expand = 'Ouvrir';
|
||||
window.l.fr.collapse = 'Réduire';
|
||||
window.l.fr.details = 'Détails';
|
||||
window.l.fr.expandFullConversation = 'montrer la totalité de la conversation';
|
||||
window.l.fr.replyVerb = 'Répondre';
|
||||
window.l.fr.requeetVerb = 'Requeeter';
|
||||
window.l.fr.favoriteVerb = 'Favori';
|
||||
window.l.fr.requeetedVerb = 'Requeeté';
|
||||
window.l.fr.favoritedVerb = 'Ajouté aux favoris';
|
||||
window.l.fr.replyTo = 'Répondre à';
|
||||
window.l.fr.requeetedBy = 'Requeeté par';
|
||||
window.l.fr.favoriteNoun = 'Favori';
|
||||
window.l.fr.favoritesNoun = 'Favoris';
|
||||
window.l.fr.requeetNoun = 'Requeet';
|
||||
window.l.fr.requeetsNoun = 'Requeets';
|
||||
window.l.fr.newQueet = 'nouveau Queet';
|
||||
window.l.fr.newQueets = 'nouveaux Queets';
|
||||
window.l.fr.longmonthsJanuary = "janvier";
|
||||
window.l.fr.longmonthsFebruary = "février";
|
||||
window.l.fr.longmonthsMars = "mars";
|
||||
window.l.fr.longmonthsApril = "avril";
|
||||
window.l.fr.longmonthsMay = "mai";
|
||||
window.l.fr.longmonthsJune = "juin";
|
||||
window.l.fr.longmonthsJuly = "juillet";
|
||||
window.l.fr.longmonthsAugust = "août";
|
||||
window.l.fr.longmonthsSeptember = "septembre";
|
||||
window.l.fr.longmonthsOctober = "octobre";
|
||||
window.l.fr.longmonthsNovember = "novembre";
|
||||
window.l.fr.longmonthsDecember = "décembre";
|
||||
window.l.fr.shortmonthsJanuary = "janv";
|
||||
window.l.fr.shortmonthsFebruary = "févr";
|
||||
window.l.fr.shortmonthsMars = "mars";
|
||||
window.l.fr.shortmonthsApril = "avril";
|
||||
window.l.fr.shortmonthsMay = "mai";
|
||||
window.l.fr.shortmonthsJune = "juin";
|
||||
window.l.fr.shortmonthsJuly = "juil";
|
||||
window.l.fr.shortmonthsAugust = "août";
|
||||
window.l.fr.shortmonthsSeptember = "sept";
|
||||
window.l.fr.shortmonthsOctober = "oct";
|
||||
window.l.fr.shortmonthsNovember = "nov";
|
||||
window.l.fr.shortmonthsDecember = "déc";
|
||||
window.l.fr.time12am = '{time} AM';
|
||||
window.l.fr.time12pm = '{time} PM';
|
||||
window.l.fr.longDateFormat = '{hours} h {minutes} - {day} {month} {year}';
|
||||
window.l.fr.shortDateFormatSeconds = '{seconds} s';
|
||||
window.l.fr.shortDateFormatMinutes = '{minutes} min';
|
||||
window.l.fr.shortDateFormatHours = '{hours} h';
|
||||
window.l.fr.shortDateFormatDate = '{day} {month}';
|
||||
window.l.fr.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.fr.now = 'en ce moment';
|
||||
window.l.fr.posting = 'envoie';
|
||||
window.l.fr.viewMoreInConvBefore = '← Voir davantage dans la conversation';
|
||||
window.l.fr.viewMoreInConvAfter = 'Voir davantage dans la conversation →';
|
||||
window.l.fr.mentions = 'Mentions';
|
||||
window.l.fr.publicTimeline = 'Tous les queets';
|
||||
window.l.fr.searchVerb = 'Rechercher';
|
||||
window.l.fr.deleteVerb = 'Supprimer';
|
||||
window.l.fr.cancelVerb = 'Annuler';
|
||||
window.l.fr.deleteConfirmation = 'Êtes-vous sûr de vouloir supprimer ce queet ?';
|
||||
window.l.fr.userFollow = 'Suivre';
|
||||
window.l.fr.userFollowing = 'Abonné';
|
||||
window.l.fr.userUnfollow = 'Se désabonner';
|
||||
window.l.fr.joinGroup = 'Rejoindre ce groupe';
|
||||
window.l.fr.isMemberOfGroup = 'Quitter le groupe';
|
||||
window.l.fr.leaveGroup = 'Quitter le groupe';
|
||||
window.l.fr.memberCount = 'Membres';
|
||||
window.l.fr.adminCount = 'Administrateurs';
|
||||
|
||||
|
||||
// deutsch
|
||||
window.l.de = new Object();
|
||||
window.l.de.languageName = 'Deutsch';
|
||||
window.l.de.loginUsername = 'Benutzername oder E-Mail';
|
||||
window.l.de.loginPassword = 'Passwort';
|
||||
window.l.de.loginSignIn = 'Anmelden';
|
||||
window.l.de.loginRememberMe = 'Angemeldet bleiben';
|
||||
window.l.de.loginForgotPassword = 'Passwort vergessen?';
|
||||
window.l.de.notices = 'Queets';
|
||||
window.l.de.followers = 'Follower';
|
||||
window.l.de.following = 'Folgt';
|
||||
window.l.de.groups = 'Gruppen';
|
||||
window.l.de.compose = 'Verfasse einen neuen Queet...';
|
||||
window.l.de.queetVerb = 'Quittern';
|
||||
window.l.de.queetsNounPlural = 'Queets';
|
||||
window.l.de.logout = 'Abmelden';
|
||||
window.l.de.languageSelected = 'Sprache:';
|
||||
window.l.de.viewMyProfilePage = 'Mein Profil ansehen';
|
||||
window.l.de.expand = 'Öffnen';
|
||||
window.l.de.collapse = 'Schließen';
|
||||
window.l.de.details = 'Details';
|
||||
window.l.de.expandFullConversation = 'Vollständige Gespräch';
|
||||
window.l.de.replyVerb = 'Antworten';
|
||||
window.l.de.requeetVerb = 'Requeeten';
|
||||
window.l.de.favoriteVerb = 'Favorisieren';
|
||||
window.l.de.requeetedVerb = 'Requeetet';
|
||||
window.l.de.favoritedVerb = 'Favorisiert';
|
||||
window.l.de.replyTo = 'Antwort an';
|
||||
window.l.de.requeetedBy = 'Requeetet von';
|
||||
window.l.de.favoriteNoun = 'Favorisieren';
|
||||
window.l.de.favoritesNoun = 'Favoriten';
|
||||
window.l.de.requeetNoun = 'Requeet';
|
||||
window.l.de.requeetsNoun = 'Requeets';
|
||||
window.l.de.newQueet = 'neuer Queet';
|
||||
window.l.de.newQueets = 'neue Queets';
|
||||
window.l.de.longmonthsJanuary = "Januar";
|
||||
window.l.de.longmonthsFebruary = "Februar";
|
||||
window.l.de.longmonthsMars = "März";
|
||||
window.l.de.longmonthsApril = "April";
|
||||
window.l.de.longmonthsMay = "Mai";
|
||||
window.l.de.longmonthsJune = "Juni";
|
||||
window.l.de.longmonthsJuly = "Juli";
|
||||
window.l.de.longmonthsAugust = "August";
|
||||
window.l.de.longmonthsSeptember = "September";
|
||||
window.l.de.longmonthsOctober = "Oktober";
|
||||
window.l.de.longmonthsNovember = "November";
|
||||
window.l.de.longmonthsDecember = "Dezember";
|
||||
window.l.de.shortmonthsJanuary = "Jan";
|
||||
window.l.de.shortmonthsFebruary = "Feb";
|
||||
window.l.de.shortmonthsMars = "Mär";
|
||||
window.l.de.shortmonthsApril = "Apr";
|
||||
window.l.de.shortmonthsMay = "Mai";
|
||||
window.l.de.shortmonthsJune = "Jun";
|
||||
window.l.de.shortmonthsJuly = "Jul";
|
||||
window.l.de.shortmonthsAugust = "Aug";
|
||||
window.l.de.shortmonthsSeptember = "Sep";
|
||||
window.l.de.shortmonthsOctober = "Okt";
|
||||
window.l.de.shortmonthsNovember = "Nov";
|
||||
window.l.de.shortmonthsDecember = "Dez";
|
||||
window.l.de.time12am = '{time} AM';
|
||||
window.l.de.time12pm = '{time} PM';
|
||||
window.l.de.longDateFormat = '{time24} - {day} {month} {year}';
|
||||
window.l.de.shortDateFormatSeconds = '{seconds}s';
|
||||
window.l.de.shortDateFormatMinutes = '{minutes}m';
|
||||
window.l.de.shortDateFormatHours = '{hours}h';
|
||||
window.l.de.shortDateFormatDate = '{day}{month}';
|
||||
window.l.de.shortDateFormatDateAndY = '{day}{month} {year}';
|
||||
window.l.de.now = 'jetzt';
|
||||
window.l.de.posting = 'Entsendung';
|
||||
window.l.de.viewMoreInConvBefore = '← Mehr im Gespräch anzeigen';
|
||||
window.l.de.viewMoreInConvAfter = 'Mehr im Gespräch anzeigen →';
|
||||
window.l.de.mentions = 'Erwähnungen';
|
||||
window.l.de.publicTimeline = 'Öffentliche Zeitleiste';
|
||||
window.l.de.searchVerb = 'Suche';
|
||||
window.l.de.deleteVerb = 'Löschen';
|
||||
window.l.de.cancelVerb = 'Abbrechen';
|
||||
window.l.de.deleteConfirmation = 'Bist Du sicher, dass Du diesen Queet löschen möchtest?';
|
||||
window.l.de.userFollow = 'Folgen';
|
||||
window.l.de.userFollowing = 'Folge ich';
|
||||
window.l.de.userUnfollow = 'Entfolgen';
|
||||
window.l.de.joinGroup = 'Der Gruppe beitreten';
|
||||
window.l.de.isMemberOfGroup = 'Gruppe verlassen';
|
||||
window.l.de.leaveGroup = 'Gruppe verlassen';
|
||||
window.l.de.memberCount = 'Mitglieder';
|
||||
window.l.de.adminCount = 'Administratoren';
|
||||
|
||||
|
||||
|
||||
// english
|
||||
window.l.en = new Object();
|
||||
window.l.en.languageName = 'English';
|
||||
window.l.en.loginUsername = 'Username or e-mail';
|
||||
window.l.en.loginPassword = 'Password';
|
||||
window.l.en.loginSignIn = 'Sign in';
|
||||
window.l.en.loginRememberMe = 'Remember me';
|
||||
window.l.en.loginForgotPassword = 'Forgot password?';
|
||||
window.l.en.notices = 'Queets';
|
||||
window.l.en.followers = 'Followers';
|
||||
window.l.en.following = 'Following';
|
||||
window.l.en.groups = 'Groups';
|
||||
window.l.en.compose = 'Compose new Queet...';
|
||||
window.l.en.queetVerb = 'Queet';
|
||||
window.l.en.queetsNounPlural = 'Queets';
|
||||
window.l.en.logout = 'Sign out';
|
||||
window.l.en.languageSelected = 'Language:';
|
||||
window.l.en.viewMyProfilePage = 'View my profile page';
|
||||
window.l.en.expand = 'Expand';
|
||||
window.l.en.collapse = 'Collapse';
|
||||
window.l.en.details = 'Details';
|
||||
window.l.en.expandFullConversation = 'Expand full conversation';
|
||||
window.l.en.replyVerb = 'Reply';
|
||||
window.l.en.requeetVerb = 'Requeet';
|
||||
window.l.en.favoriteVerb = 'Favorite';
|
||||
window.l.en.requeetedVerb = 'Requeeted';
|
||||
window.l.en.favoritedVerb = 'Favorited';
|
||||
window.l.en.replyTo = 'Reply to';
|
||||
window.l.en.requeetedBy = 'Requeeted by';
|
||||
window.l.en.favoriteNoun = 'Favorite';
|
||||
window.l.en.favoritesNoun = 'Favorites';
|
||||
window.l.en.requeetNoun = 'Requeet';
|
||||
window.l.en.requeetsNoun = 'Requeets';
|
||||
window.l.en.newQueet = 'new Queet';
|
||||
window.l.en.newQueets = 'new Queets';
|
||||
window.l.en.longmonthsJanuary = "January";
|
||||
window.l.en.longmonthsFebruary = "February";
|
||||
window.l.en.longmonthsMars = "Mars";
|
||||
window.l.en.longmonthsApril = "April";
|
||||
window.l.en.longmonthsMay = "May";
|
||||
window.l.en.longmonthsJune = "June";
|
||||
window.l.en.longmonthsJuly = "July";
|
||||
window.l.en.longmonthsAugust = "August";
|
||||
window.l.en.longmonthsSeptember = "September";
|
||||
window.l.en.longmonthsOctober = "October";
|
||||
window.l.en.longmonthsNovember = "November";
|
||||
window.l.en.longmonthsDecember = "December";
|
||||
window.l.en.shortmonthsJanuary = "jan";
|
||||
window.l.en.shortmonthsFebruary = "feb";
|
||||
window.l.en.shortmonthsMars = "mar";
|
||||
window.l.en.shortmonthsApril = "apr";
|
||||
window.l.en.shortmonthsMay = "may";
|
||||
window.l.en.shortmonthsJune = "jun";
|
||||
window.l.en.shortmonthsJuly = "jul";
|
||||
window.l.en.shortmonthsAugust = "aug";
|
||||
window.l.en.shortmonthsSeptember = "sep";
|
||||
window.l.en.shortmonthsOctober = "oct";
|
||||
window.l.en.shortmonthsNovember = "nov";
|
||||
window.l.en.shortmonthsDecember = "dec";
|
||||
window.l.en.time12am = '{time} am';
|
||||
window.l.en.time12pm = '{time} pm';
|
||||
window.l.en.longDateFormat = '{time12} - {day} {month} {year}';
|
||||
window.l.en.shortDateFormatSeconds = '{seconds}s';
|
||||
window.l.en.shortDateFormatMinutes = '{minutes}m';
|
||||
window.l.en.shortDateFormatHours = '{hours}h';
|
||||
window.l.en.shortDateFormatDate = '{day} {month}';
|
||||
window.l.en.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.en.now = 'now';
|
||||
window.l.en.posting = 'posting';
|
||||
window.l.en.viewMoreInConvBefore = '← View more in conversation';
|
||||
window.l.en.viewMoreInConvAfter = 'View more in conversation →';
|
||||
window.l.en.mentions = 'Mentions';
|
||||
window.l.en.publicTimeline = 'Public Timeline';
|
||||
window.l.en.searchVerb = 'Search';
|
||||
window.l.en.deleteVerb = 'Delete';
|
||||
window.l.en.cancelVerb = 'Cancel';
|
||||
window.l.en.deleteConfirmation = 'Are you sure you want to delete this queet?';
|
||||
window.l.en.userFollow = 'Follow';
|
||||
window.l.en.userFollowing = 'Following';
|
||||
window.l.en.userUnfollow = 'Unfollow';
|
||||
window.l.en.joinGroup = 'Join';
|
||||
window.l.en.isMemberOfGroup = 'Member';
|
||||
window.l.en.leaveGroup = 'Leave';
|
||||
window.l.en.memberCount = 'Members';
|
||||
window.l.en.adminCount = 'Admins';
|
||||
|
||||
|
||||
|
||||
// svenska
|
||||
window.l.sv = new Object();
|
||||
window.l.sv.languageName = 'Svenska';
|
||||
window.l.sv.loginUsername = 'Användarnamn eller mejladress';
|
||||
window.l.sv.loginPassword = 'Lösenord';
|
||||
window.l.sv.loginSignIn = 'Logga in';
|
||||
window.l.sv.loginRememberMe = 'Kom ihåg mig';
|
||||
window.l.sv.loginForgotPassword = 'Glömt lösenordet?';
|
||||
window.l.sv.notices = 'Qvittrat';
|
||||
window.l.sv.followers = 'Följare';
|
||||
window.l.sv.following = 'Följer';
|
||||
window.l.sv.groups = 'Grupper';
|
||||
window.l.sv.compose = 'Skriv nytt qvitter';
|
||||
window.l.sv.queetVerb = 'Qvittra';
|
||||
window.l.sv.queetsNounPlural = 'Qvitter';
|
||||
window.l.sv.logout = 'Logga ut';
|
||||
window.l.sv.languageSelected = 'Språk:';
|
||||
window.l.sv.viewMyProfilePage = 'Visa min profilsida';
|
||||
window.l.sv.expand = 'Visa';
|
||||
window.l.sv.collapse = 'Stäng';
|
||||
window.l.sv.details = 'Detaljer';
|
||||
window.l.sv.expandFullConversation = 'Visa hela konversationen';
|
||||
window.l.sv.replyVerb = 'Svara';
|
||||
window.l.sv.requeetVerb = 'Requeeta';
|
||||
window.l.sv.favoriteVerb = 'Favoritmarkera';
|
||||
window.l.sv.requeetedVerb = 'Requeetad';
|
||||
window.l.sv.favoritedVerb = 'Favoritmarkerad';
|
||||
window.l.sv.replyTo = 'Svara';
|
||||
window.l.sv.requeetedBy = 'requeetad av';
|
||||
window.l.sv.favoriteNoun = 'favorit';
|
||||
window.l.sv.favoritesNoun = 'Favoriter';
|
||||
window.l.sv.requeetNoun = 'requeet';
|
||||
window.l.sv.requeetsNoun = 'requeets';
|
||||
window.l.sv.newQueet = 'nytt qvitter';
|
||||
window.l.sv.newQueets = 'nya qvitter';
|
||||
window.l.sv.longmonthsJanuary = "januari";
|
||||
window.l.sv.longmonthsFebruary = "februari";
|
||||
window.l.sv.longmonthsMars = "mars";
|
||||
window.l.sv.longmonthsApril = "april";
|
||||
window.l.sv.longmonthsMay = "maj";
|
||||
window.l.sv.longmonthsJune = "juni";
|
||||
window.l.sv.longmonthsJuly = "juli";
|
||||
window.l.sv.longmonthsAugust = "augusti";
|
||||
window.l.sv.longmonthsSeptember = "september";
|
||||
window.l.sv.longmonthsOctober = "oktober";
|
||||
window.l.sv.longmonthsNovember = "november";
|
||||
window.l.sv.longmonthsDecember = "december";
|
||||
window.l.sv.shortmonthsJanuary = "jan";
|
||||
window.l.sv.shortmonthsFebruary = "feb";
|
||||
window.l.sv.shortmonthsMars = "mar";
|
||||
window.l.sv.shortmonthsApril = "apr";
|
||||
window.l.sv.shortmonthsMay = "maj";
|
||||
window.l.sv.shortmonthsJune = "jun";
|
||||
window.l.sv.shortmonthsJuly = "jul";
|
||||
window.l.sv.shortmonthsAugust = "aug";
|
||||
window.l.sv.shortmonthsSeptember = "sep";
|
||||
window.l.sv.shortmonthsOctober = "okt";
|
||||
window.l.sv.shortmonthsNovember = "nov";
|
||||
window.l.sv.shortmonthsDecember = "dec";
|
||||
window.l.sv.time12am = '{time} f.m.';
|
||||
window.l.sv.time12pm = '{time} e.m.';
|
||||
window.l.sv.longDateFormat = '{time24} - {day} {month} {year}';
|
||||
window.l.sv.shortDateFormatSeconds = '{seconds}s';
|
||||
window.l.sv.shortDateFormatMinutes = '{minutes}m';
|
||||
window.l.sv.shortDateFormatHours = '{hours}h';
|
||||
window.l.sv.shortDateFormatDate = '{day} {month}';
|
||||
window.l.sv.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.sv.now = 'nyss';
|
||||
window.l.sv.posting = 'postar';
|
||||
window.l.sv.viewMoreInConvBefore = '← Visa mer i konversationen';
|
||||
window.l.sv.viewMoreInConvAfter = 'Visa mer i konversationen →';
|
||||
window.l.sv.mentions = 'Omnämnanden';
|
||||
window.l.sv.publicTimeline = 'Hela sajtens flöde';
|
||||
window.l.sv.searchVerb = 'Sök';
|
||||
window.l.sv.deleteVerb = 'Ta bort';
|
||||
window.l.sv.cancelVerb = 'Avbryt';
|
||||
window.l.sv.deleteConfirmation = 'Är du säker på att du vill radera denna queet?';
|
||||
window.l.sv.userFollow = 'Följ';
|
||||
window.l.sv.userFollowing = 'Följer';
|
||||
window.l.sv.userUnfollow = 'Avfölj';
|
||||
window.l.sv.joinGroup = 'Gå med';
|
||||
window.l.sv.isMemberOfGroup = 'Medlem';
|
||||
window.l.sv.leaveGroup = 'Gå ur';
|
||||
window.l.sv.memberCount = 'Medlemmar';
|
||||
window.l.sv.adminCount = 'Administratörer';
|
||||
|
||||
|
||||
|
||||
// farsi/persian
|
||||
window.l.fa = new Object();
|
||||
window.l.fa.languageName = 'فارسی';
|
||||
window.l.fa.loginUsername = 'شناسه یا ایمیل';
|
||||
window.l.fa.loginPassword = 'گذرواژه - رمز عبور';
|
||||
window.l.fa.loginSignIn = 'ورود';
|
||||
window.l.fa.loginRememberMe = 'مرا به یاد داشته باش';
|
||||
window.l.fa.loginForgotPassword = 'گذرواژه خود را فراموش کردهاید؟';
|
||||
window.l.fa.notices = 'توییت';
|
||||
window.l.fa.followers = 'دنبالکننده';
|
||||
window.l.fa.following = 'دنبالشونده';
|
||||
window.l.fa.groups = 'گروه';
|
||||
window.l.fa.compose = 'نوشتن یک توییت تازه...';
|
||||
window.l.fa.queetVerb = 'توییت';
|
||||
window.l.fa.queetsNounPlural = 'توييتها';
|
||||
window.l.fa.logout = 'خروج';
|
||||
window.l.fa.languageSelected = 'زبان:';
|
||||
window.l.fa.viewMyProfilePage = 'دیدن صفحه نمایه';
|
||||
window.l.fa.expand = 'گستردن';
|
||||
window.l.fa.collapse = 'بستن';
|
||||
window.l.fa.details = 'جزئیات';
|
||||
window.l.fa.expandFullConversation = 'نمایش مکالمه کامل';
|
||||
window.l.fa.replyVerb = 'پاسخ';
|
||||
window.l.fa.requeetVerb = 'بازتوییت';
|
||||
window.l.fa.favoriteVerb = 'برگزیدن';
|
||||
window.l.fa.requeetedVerb = 'بازتوییت شده';
|
||||
window.l.fa.favoritedVerb = 'برگزیده شده';
|
||||
window.l.fa.replyTo = 'پاسخ به';
|
||||
window.l.fa.requeetedBy = 'بازتوییت شده توسط';
|
||||
window.l.fa.favoriteNoun = 'برگزیده';
|
||||
window.l.fa.favoritesNoun = 'برگزیده';
|
||||
window.l.fa.requeetNoun = 'بازتوییت';
|
||||
window.l.fa.requeetsNoun = 'بازتوییت';
|
||||
window.l.fa.newQueet = 'توییت جدید';
|
||||
window.l.fa.newQueets = 'توییت جدید';
|
||||
window.l.fa.longmonthsJanuary = "ژانويه";
|
||||
window.l.fa.longmonthsFebruary = "فوريه";
|
||||
window.l.fa.longmonthsMars = "مارس";
|
||||
window.l.fa.longmonthsApril = "اوريل";
|
||||
window.l.fa.longmonthsMay = "مه";
|
||||
window.l.fa.longmonthsJune = "ژوءن";
|
||||
window.l.fa.longmonthsJuly = "ژوءيه";
|
||||
window.l.fa.longmonthsAugust = "اوت";
|
||||
window.l.fa.longmonthsSeptember = "سپتامبر";
|
||||
window.l.fa.longmonthsOctober = "اكتبر";
|
||||
window.l.fa.longmonthsNovember = "نوامبر";
|
||||
window.l.fa.longmonthsDecember = "دسامبر";
|
||||
window.l.fa.shortmonthsJanuary = "ژانويه";
|
||||
window.l.fa.shortmonthsFebruary = "فوريه";
|
||||
window.l.fa.shortmonthsMars = "مارس";
|
||||
window.l.fa.shortmonthsApril = "اوريل";
|
||||
window.l.fa.shortmonthsMay = "مه";
|
||||
window.l.fa.shortmonthsJune = "ژوءن";
|
||||
window.l.fa.shortmonthsJuly = "ژوءيه";
|
||||
window.l.fa.shortmonthsAugust = "اوت";
|
||||
window.l.fa.shortmonthsSeptember = "سپتامبر";
|
||||
window.l.fa.shortmonthsOctober = "اكتبر";
|
||||
window.l.fa.shortmonthsNovember = "نوامبر";
|
||||
window.l.fa.shortmonthsDecember = "دسامبر";
|
||||
window.l.fa.time12am = '{time} am';
|
||||
window.l.fa.time12pm = '{time} pm';
|
||||
window.l.fa.longDateFormat = '{time24} - {day} {month} {year}';
|
||||
window.l.fa.shortDateFormatSeconds = '{seconds} ثانیه';
|
||||
window.l.fa.shortDateFormatMinutes = '{minutes} دقیقه';
|
||||
window.l.fa.shortDateFormatHours = '{hours} ساعت';
|
||||
window.l.fa.shortDateFormatDate = '{day} {month}';
|
||||
window.l.fa.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.fa.now = 'فقط در حال حاضر';
|
||||
window.l.fa.posting = 'می فرستد';
|
||||
window.l.fa.viewMoreInConvBefore = '→ نمایش بیشتر در گفتگوها';
|
||||
window.l.fa.viewMoreInConvAfter = 'نمایش بیشتر در گفتگوها ←';
|
||||
window.l.fa.mentions = 'رونوشتها';
|
||||
window.l.fa.publicTimeline = 'خطزمانی عمومی';
|
||||
window.l.fa.searchVerb = 'جستجو';
|
||||
window.l.fa.deleteVerb = 'حذف';
|
||||
window.l.fa.cancelVerb = 'لغو';
|
||||
window.l.fa.deleteConfirmation = 'آیا مطمئن هستید که میخواهید این توییت را پاک کنید؟';
|
||||
window.l.fa.userFollow = 'دنبال کنید';
|
||||
window.l.fa.userFollowing = 'دنبال میکنید';
|
||||
window.l.fa.userUnfollow = 'دنبال نكن';
|
||||
window.l.fa.joinGroup = 'پیوستن به گروه';
|
||||
window.l.fa.isMemberOfGroup = 'ترک گروه';
|
||||
window.l.fa.leaveGroup = 'ترک گروه';
|
||||
window.l.fa.memberCount = 'اعضای';
|
||||
window.l.fa.adminCount = 'مدیران';
|
||||
|
||||
|
||||
|
||||
// arabic
|
||||
window.l.ar = new Object();
|
||||
window.l.ar.languageName = 'العربيّة';
|
||||
window.l.ar.loginUsername = 'اسم المستخدم أو البريد الإلكترونيّ';
|
||||
window.l.ar.loginPassword = 'كلمة المرور';
|
||||
window.l.ar.loginSignIn = 'تسجيل الدخول';
|
||||
window.l.ar.loginRememberMe = 'تذكّرني';
|
||||
window.l.ar.loginForgotPassword = 'نسيت كلمة المرور؟';
|
||||
window.l.ar.notices = 'تغريدات';
|
||||
window.l.ar.followers = 'متابِعين';
|
||||
window.l.ar.following = 'متابَعين';
|
||||
window.l.ar.groups = 'جماعة';
|
||||
window.l.ar.compose = 'اكتب تغريدة جديدة...';
|
||||
window.l.ar.queetVerb = 'تغريد';
|
||||
window.l.ar.queetsNounPlural = 'تغريدات';
|
||||
window.l.ar.logout = 'تسجيل الخروج';
|
||||
window.l.ar.languageSelected = 'اللغة:';
|
||||
window.l.ar.viewMyProfilePage = 'عرض صفحة ملفي الشخصي';
|
||||
window.l.ar.expand = 'فتح';
|
||||
window.l.ar.collapse = 'إغلاق';
|
||||
window.l.ar.details = 'التفاصيل';
|
||||
window.l.ar.expandFullConversation = 'مشاهدة المحادثة';
|
||||
window.l.ar.replyVerb = 'رَد';
|
||||
window.l.ar.requeetVerb = 'إعادة تغريد';
|
||||
window.l.ar.favoriteVerb = 'تفضيل';
|
||||
window.l.ar.requeetedVerb = 'مُعاد تغريدها';
|
||||
window.l.ar.favoritedVerb = 'مُفضّلة';
|
||||
window.l.ar.replyTo = 'أرسِل ردًا إلى';
|
||||
window.l.ar.requeetedBy = 'مُعاد تغريدها بواسطة';
|
||||
window.l.ar.favoriteNoun = 'مفضّلة';
|
||||
window.l.ar.favoritesNoun = 'مفضّلة';
|
||||
window.l.ar.requeetNoun = 'إعادة تغريد';
|
||||
window.l.ar.requeetsNoun = 'إعادة تغريد';
|
||||
window.l.ar.newQueet = 'تغريدة جديدة';
|
||||
window.l.ar.newQueets = 'تغريدة جديدة';
|
||||
window.l.ar.longmonthsJanuary = "يناير";
|
||||
window.l.ar.longmonthsFebruary = "فبراير";
|
||||
window.l.ar.longmonthsMars = "مارس";
|
||||
window.l.ar.longmonthsApril = "أبريل";
|
||||
window.l.ar.longmonthsMay = "مايو";
|
||||
window.l.ar.longmonthsJune = "يونيو";
|
||||
window.l.ar.longmonthsJuly = "يوليو";
|
||||
window.l.ar.longmonthsAugust = "أغسطس";
|
||||
window.l.ar.longmonthsSeptember = "سبتمبر";
|
||||
window.l.ar.longmonthsOctober = "أكتوبر";
|
||||
window.l.ar.longmonthsNovember = "نوفمبر";
|
||||
window.l.ar.longmonthsDecember = "ديسمبر";
|
||||
window.l.ar.shortmonthsJanuary = "يناير";
|
||||
window.l.ar.shortmonthsFebruary = "فبراير";
|
||||
window.l.ar.shortmonthsMars = "مارس";
|
||||
window.l.ar.shortmonthsApril = "أبريل";
|
||||
window.l.ar.shortmonthsMay = "مايو";
|
||||
window.l.ar.shortmonthsJune = "يونيو";
|
||||
window.l.ar.shortmonthsJuly = "يوليو";
|
||||
window.l.ar.shortmonthsAugust = "أغسطس";
|
||||
window.l.ar.shortmonthsSeptember = "سبتمبر";
|
||||
window.l.ar.shortmonthsOctober = "أكتوبر";
|
||||
window.l.ar.shortmonthsNovember = "نوفمبر";
|
||||
window.l.ar.shortmonthsDecember = "ديسمبر";
|
||||
window.l.ar.time12am = '{time} صباحًا';
|
||||
window.l.ar.time12pm = '{time} مساءً';
|
||||
window.l.ar.longDateFormat = '{time12} - {day} {month} {year}';
|
||||
window.l.ar.shortDateFormatSeconds = '{seconds} ث';
|
||||
window.l.ar.shortDateFormatMinutes = '{minutes} د';
|
||||
window.l.ar.shortDateFormatHours = '{hours} س';
|
||||
window.l.ar.shortDateFormatDate = '{day} {month}';
|
||||
window.l.ar.shortDateFormatDateAndY = '{day} {month} {year}';
|
||||
window.l.ar.now = 'الآن';
|
||||
window.l.ar.posting = 'إرسال';
|
||||
window.l.ar.viewMoreInConvBefore = '→ عرض المزيد في المحادثة';
|
||||
window.l.ar.viewMoreInConvAfter = 'عرض المزيد في المحادثة ←';
|
||||
window.l.ar.mentions = 'الإشارات';
|
||||
window.l.ar.publicTimeline = 'المسار الزمني العام';
|
||||
window.l.ar.searchVerb = 'بحث';
|
||||
window.l.ar.deleteVerb = 'حذف';
|
||||
window.l.ar.cancelVerb = 'إلغاء';
|
||||
window.l.ar.deleteConfirmation = 'هل أنت متأكد أنك تريد حذف هذه التغريدة؟';
|
||||
window.l.ar.userFollow = 'تابِع';
|
||||
window.l.ar.userFollowing = 'مُتابَع';
|
||||
window.l.ar.userUnfollow = 'إلغاء المتابعة';
|
||||
window.l.ar.joinGroup = 'الانضمام إلى المجموعة';
|
||||
window.l.ar.isMemberOfGroup = 'مغادرة المجموعة';
|
||||
window.l.ar.leaveGroup = 'مغادرة المجموعة';
|
||||
window.l.ar.memberCount = 'الأعضاء';
|
||||
window.l.ar.adminCount = 'الإداريين';
|
||||
|
||||
|
||||
|
||||
// set language, from local storage, else browser language, else english
|
||||
var browserLang = navigator.language || navigator.userLanguage;
|
||||
var selectedLanguage = 'en';
|
||||
if(typeof localStorage.selectedLanguage != 'undefined') {
|
||||
selectedLanguage = localStorage.selectedLanguage;
|
||||
}
|
||||
else if(typeof window.l[browserLang.substring(0,2)] != 'undefined') {
|
||||
selectedLanguage = browserLang.substring(0,2);
|
||||
}
|
||||
window.sL = window.l[selectedLanguage];
|
||||
|
||||
// if this is a RTL-language, add rt classes and change some things
|
||||
if(selectedLanguage == 'ar') {
|
||||
$('body').addClass('rtl');
|
||||
$('#birds-top').attr('src',window.fullUrlToThisQvitterApp + 'img/birds_rtl.png');
|
||||
$('title').html('‫ترك');
|
||||
}
|
||||
else if(selectedLanguage == 'fa') {
|
||||
$('body').addClass('rtl');
|
||||
$('#birds-top').attr('src', window.fullUrlToThisQvitterApp + 'img/birds_rtl.png');
|
||||
$('title').html('‫واگذارنده');
|
||||
}
|
||||
|
||||
window.siteTitle = $('head title').html(); // remember this for later use
|
||||
|
||||
// set some static string
|
||||
$('#username').attr('placeholder',window.sL.loginUsername);
|
||||
$('#password').attr('placeholder',window.sL.loginPassword);
|
||||
$('button#submit-login').html(window.sL.loginSignIn);
|
||||
$('#rememberme_label').html(window.sL.loginRememberMe);
|
||||
$('#remember-forgot a').html(window.sL.loginForgotPassword);
|
||||
$('#user-queets .label').html(window.sL.notices);
|
||||
$('#user-following .label').html(window.sL.following);
|
||||
$('#user-followers .label').html(window.sL.followers);
|
||||
$('#user-groups .label').html(window.sL.groups);
|
||||
$('#queet-box').html(window.sL.compose);
|
||||
$('#queet').html(window.sL.queetVerb);
|
||||
$('#feed-header-inner h2').html(window.sL.queetsNounPlural);
|
||||
$('#logout').html(window.sL.logout);
|
||||
$('.language-dropdown .dropdown-toggle small').html(window.sL.languageSelected);
|
||||
$('.language-dropdown .current-language').html(window.sL.languageName);
|
||||
$('.stream-selection[data-stream-name="statuses/friends_timeline.json"]').prepend(window.sL.queetsNounPlural);
|
||||
$('.stream-selection[data-stream-name="statuses/friends_timeline.json"]').attr('data-stream-header',window.sL.queetsNounPlural);
|
||||
$('.stream-selection[data-stream-name="statuses/mentions.json"]').prepend(window.sL.mentions);
|
||||
$('.stream-selection[data-stream-name="statuses/mentions.json"]').attr('data-stream-header',window.sL.mentions);
|
||||
$('.stream-selection[data-stream-name="favorites.json"]').prepend(window.sL.favoritesNoun);
|
||||
$('.stream-selection[data-stream-name="favorites.json"]').attr('data-stream-header',window.sL.favoritesNoun);
|
||||
$('.stream-selection[data-stream-name="statuses/public_timeline.json"]').prepend(window.sL.publicTimeline);
|
||||
$('.stream-selection[data-stream-name="statuses/public_timeline.json"]').attr('data-stream-header',window.sL.publicTimeline);
|
||||
$('#search-query').attr('placeholder',window.sL.searchVerb);
|
401
js/misc-functions-1.js
Normal file
|
@ -0,0 +1,401 @@
|
|||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Right-to-left language detection <o
|
||||
· (//
|
||||
· @param s: the stream-item to detect rtl in
|
||||
·
|
||||
· @return a stream-item that might have rtl-class added
|
||||
·
|
||||
· · · · · · · · · */
|
||||
|
||||
function detectRTL(s) {
|
||||
var $streamItem = $('<div>').append(s);
|
||||
var $queetText = $('<div>').append($streamItem.find('.queet-text').html()); // create an jquery object
|
||||
var $a = $queetText.find('a'); $a.remove(); // remove links
|
||||
var $vcard = $queetText.find('.vcard'); $vcard.remove(); // remove users, groups
|
||||
var $tag = $queetText.find('.tag'); $tag.remove(); // remove tags
|
||||
if($queetText.find('.rtl').length>0) { $queetText.html($queetText.find('.rtl').html()); } // remove rtl container if there is one
|
||||
// remove chars we're not interested in
|
||||
$queetText.html($queetText.html().replace(/\@/gi,'').replace(/\#/gi,'').replace(/\!/gi,'').replace(/\(/gi,'').replace(/\)/gi,'').replace(/\:D/gi,'').replace(/D\:/gi,'').replace(/\:/gi,'').replace(/\-/gi,'').replace(/\s/gi, ''));
|
||||
// count ltr and rtl chars
|
||||
var ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF'+'\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF',
|
||||
rtlChars = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC',
|
||||
rtlDirCheck = new RegExp('^[^'+ltrChars+']*['+rtlChars+']'),
|
||||
RTLnum = 0,
|
||||
LTRnum = 0,
|
||||
RTLorLTR = $queetText.html();
|
||||
for (var i = 0, len = RTLorLTR.length; i < len; i++) {
|
||||
if(rtlDirCheck.test(RTLorLTR[i])) { RTLnum++; }
|
||||
else { LTRnum++; }
|
||||
}
|
||||
// if there are more rtl chars than ltr
|
||||
if(RTLnum > LTRnum) { $streamItem.children('.stream-item').children('.queet').addClass('rtl'); }
|
||||
// if no chars (that we are interested, but body is set to rtl)
|
||||
else if ($queetText.html().length==0 && $('body').hasClass('rtl')) {
|
||||
$streamItem.children('.stream-item').children('.queet').addClass('rtl');
|
||||
}
|
||||
return $streamItem.html().replace(/@<span class="vcard">/gi,'<span class="vcard">').replace(/!<span class="vcard">/gi,'<span class="vcard">').replace(/#<span class="tag">/gi,'<span class="tag">'); // hacky way to get @#! into mention tags to stop bidirection (css sets an @ with before content method)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Takes twitter style dates and converts them
|
||||
·
|
||||
· @param tdate: date in the form of e.g. 'Mon Aug 05 16:30:22 +0200 2013'
|
||||
·
|
||||
· @return user friendly dates ..M_
|
||||
· W
|
||||
· Needs global language object window.sL to be populated
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function parseTwitterDate(tdate) {
|
||||
var month_names = new Array ();
|
||||
month_names[month_names.length] = window.sL.shortmonthsJanuary;
|
||||
month_names[month_names.length] = window.sL.shortmonthsFebruary
|
||||
month_names[month_names.length] = window.sL.shortmonthsMars
|
||||
month_names[month_names.length] = window.sL.shortmonthsApril
|
||||
month_names[month_names.length] = window.sL.shortmonthsMay
|
||||
month_names[month_names.length] = window.sL.shortmonthsJune
|
||||
month_names[month_names.length] = window.sL.shortmonthsJuly
|
||||
month_names[month_names.length] = window.sL.shortmonthsAugust
|
||||
month_names[month_names.length] = window.sL.shortmonthsSeptember
|
||||
month_names[month_names.length] = window.sL.shortmonthsOctober
|
||||
month_names[month_names.length] = window.sL.shortmonthsNovember
|
||||
month_names[month_names.length] = window.sL.shortmonthsDecember
|
||||
var system_date = new Date(Date.parse(tdate));
|
||||
var user_date = new Date();
|
||||
var diff = Math.floor((user_date - system_date) / 1000);
|
||||
if (diff <= 10) {return window.sL.now;}
|
||||
if (diff < 60) {return window.sL.shortDateFormatSeconds.replace('{seconds}',Math.round(diff/10)*10);}
|
||||
if (diff <= 3540) {return window.sL.shortDateFormatMinutes.replace('{minutes}',Math.round(diff / 60));}
|
||||
if (diff <= 86400) {return window.sL.shortDateFormatHours.replace('{hours}',Math.round(diff / 3600));}
|
||||
if (diff <= 31536000) {return window.sL.shortDateFormatDate.replace('{day}',system_date.getDate()).replace('{month}',month_names[system_date.getMonth()]);}
|
||||
if (diff > 31536000) {return window.sL.shortDateFormatDateAndY.replace('{day}',system_date.getDate()).replace('{month}',month_names[system_date.getMonth()]).replace('{year}',system_date.getFullYear());}
|
||||
return system_date;
|
||||
}
|
||||
function parseTwitterLongDate(tdate) {
|
||||
var month_names = new Array ();
|
||||
month_names[month_names.length] = window.sL.longmonthsJanuary;
|
||||
month_names[month_names.length] = window.sL.longmonthsFebruary
|
||||
month_names[month_names.length] = window.sL.longmonthsMars
|
||||
month_names[month_names.length] = window.sL.longmonthsApril
|
||||
month_names[month_names.length] = window.sL.longmonthsMay
|
||||
month_names[month_names.length] = window.sL.longmonthsJune
|
||||
month_names[month_names.length] = window.sL.longmonthsJuly
|
||||
month_names[month_names.length] = window.sL.longmonthsAugust
|
||||
month_names[month_names.length] = window.sL.longmonthsSeptember
|
||||
month_names[month_names.length] = window.sL.longmonthsOctober
|
||||
month_names[month_names.length] = window.sL.longmonthsNovember
|
||||
month_names[month_names.length] = window.sL.longmonthsDecember
|
||||
var system_date = new Date(Date.parse(tdate));
|
||||
var hours = system_date.getHours();
|
||||
var minutes = ('0'+system_date.getMinutes()).slice(-2);
|
||||
var ampm = hours >= 12 ? 'pm' : 'am';
|
||||
var time24hours = hours + ':' + minutes;
|
||||
var time12hours = hours % 12;
|
||||
time12hours = time12hours ? time12hours : 12; // the hour '0' should be '12'
|
||||
if(ampm == 'am') { time12hours = window.sL.time12am.replace('{time}',time12hours + ':' + minutes);}
|
||||
else { time12hours = window.sL.time12pm.replace('{time}',time12hours + ':' + minutes); }
|
||||
return window.sL.longDateFormat.replace('{time24}',time24hours).replace('{hours}',hours).replace('{minutes}',minutes).replace('{time12}',time12hours).replace('{day}',system_date.getDate()).replace('{month}',month_names[system_date.getMonth()]).replace('{year}',system_date.getFullYear());
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Return all URL:s in a string
|
||||
·
|
||||
· @param string: the string to search
|
||||
·
|
||||
· @return an array with the found urls
|
||||
·
|
||||
· · · · · · · · · · */
|
||||
|
||||
function findUrls(text) {
|
||||
var source = (text || '').toString();
|
||||
var urlArray = [];
|
||||
var url;
|
||||
var matchArray;
|
||||
var regexToken = /(((ftp|https?):\/\/)[\-\w@:%_\+.~#?,&\/\/=]+)|((mailto:)?[_.\w-]+@([\w][\w\-]+\.)+[a-zA-Z]{2,3})/g;
|
||||
while( (matchArray = regexToken.exec( source )) !== null ) {
|
||||
var token = matchArray[0];
|
||||
urlArray.push( token );
|
||||
}
|
||||
return urlArray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Functions to show and remove the spinner
|
||||
·
|
||||
· · · · · · · · · · · · */
|
||||
|
||||
function display_spinner() {
|
||||
if($('.spinner-wrap').length==0) {
|
||||
$('body').prepend('<div class="spinner-wrap"><div class="spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></div>');
|
||||
}
|
||||
}
|
||||
function remove_spinner() {
|
||||
$('.spinner-wrap').remove();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Converts ...-attachment-links to spans
|
||||
·
|
||||
· (Attachments are loaded when queets expand)
|
||||
·
|
||||
· · · · · · · · · · · · · · · · · */
|
||||
|
||||
function convertAttachmentMoreHref() {
|
||||
$('a.attachment.more').each(function() {
|
||||
if(typeof $(this).attr('href') != 'undefined') {
|
||||
$(this).replaceWith($('<span class="attachment more" data-attachment-id="' + $(this).attr('href').substring(29) + '">…</span>'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Places the caret at the end of the contenteditable
|
||||
·
|
||||
· @param el: the contenteditable-element
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function placeCaretAtEnd(el) {
|
||||
el.focus();
|
||||
if (typeof window.getSelection != "undefined"
|
||||
&& typeof document.createRange != "undefined") {
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(el);
|
||||
range.collapse(false);
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
} else if (typeof document.body.createTextRange != "undefined") {
|
||||
var textRange = document.body.createTextRange();
|
||||
textRange.moveToElementText(el);
|
||||
textRange.collapse(false);
|
||||
textRange.select();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Updates the local storage
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function updateHistoryLocalStorage() {
|
||||
var i=0;
|
||||
var localStorageName = window.username + '-history-container';
|
||||
var historyContainer = new Object();
|
||||
$.each($('#history-container .stream-selection'), function(key,obj) {
|
||||
historyContainer[i] = new Object();
|
||||
historyContainer[i].dataStreamName = $(obj).attr('data-stream-name');
|
||||
historyContainer[i].dataStreamHeader = $(obj).attr('data-stream-header');
|
||||
i++;
|
||||
});
|
||||
localStorage[localStorageName] = JSON.stringify(historyContainer);
|
||||
if($('#history-container .stream-selection').length==0) {
|
||||
$('#history-container').css('display','none');
|
||||
}
|
||||
else {
|
||||
$('#history-container').css('display','block');
|
||||
}
|
||||
$('#history-container').sortable({delay: 100});
|
||||
$('#history-container').disableSelection();
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Loads history from local storage to menu
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function loadHistoryFromLocalStorage() {
|
||||
var localStorageName = window.username + '-history-container';
|
||||
if(typeof localStorage[localStorageName] != "undefined") {
|
||||
$('#history-container').css('display','block');
|
||||
$('#history-container').html('');
|
||||
var historyContainer = $.parseJSON(localStorage[localStorageName]);
|
||||
$.each(historyContainer, function(key,obj) {
|
||||
$('#history-container').append('<div class="stream-selection" data-stream-header="' + obj.dataStreamHeader + '" data-stream-name="' + obj.dataStreamName + '">' + obj.dataStreamHeader + '<i class="close-right"></i><i class="chev-right"></i></div>');
|
||||
});
|
||||
}
|
||||
updateHistoryLocalStorage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Does stream need a ? or a &
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function qOrAmp(stream) {
|
||||
if(stream.substr(-5) == '.json') {
|
||||
return '?';
|
||||
}
|
||||
else {
|
||||
return '&';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Count chars in queet box
|
||||
·
|
||||
· @param src: the queetbox
|
||||
· @param trgt: the counter
|
||||
· @param btn: the button
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function countCharsInQueetBox(src,trgt,btn) {
|
||||
var $src_txt = $('<div/>').append($.trim(src.html()).replace(/ /gi,'').replace(/<br>/i,'').replace(/<br>/gi,"x"));
|
||||
var numchars = ($.trim($src_txt.text())).length;
|
||||
trgt.html(140 - numchars);
|
||||
|
||||
// activate/deactivare button
|
||||
if(src.html().replace(/\s/g, '').replace(/ /gi,'').replace(/<br>/gi,'') != unescape(src.attr('data-start-html')).replace(/\s/g, '').replace(/ /gi,'').replace(/<br>/gi,'')) {
|
||||
if(src.text().replace(/\s/g, '').replace(/ /gi,'').replace(/<br>/gi,'').length==0) {
|
||||
btn.removeClass('enabled');
|
||||
btn.addClass('disabled');
|
||||
}
|
||||
else if((140-numchars) < 0) {
|
||||
btn.removeClass('enabled');
|
||||
btn.addClass('disabled');
|
||||
}
|
||||
else {
|
||||
btn.removeClass('disabled');
|
||||
btn.addClass('enabled');
|
||||
}
|
||||
}
|
||||
else {
|
||||
btn.removeClass('enabled');
|
||||
btn.addClass('disabled');
|
||||
}
|
||||
|
||||
// counter color
|
||||
if((140-numchars) < 0) {
|
||||
trgt.css('color','#D40D12');
|
||||
}
|
||||
else if(src.html().length == 0 || src.html() == '<br>' || src.html() == '<br />') {
|
||||
trgt.removeAttr('style');
|
||||
}
|
||||
else {
|
||||
trgt.removeAttr('style');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Remember my scroll position
|
||||
·
|
||||
· @param obj: jQuery object which position we want to remember
|
||||
· @param id: id for position to remember
|
||||
· @param offset: we might want to offset our remembered scroll, e.g. when stream-item gets margin after expand
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function rememberMyScrollPos(obj,id,offset) {
|
||||
if(typeof offset == 'undefined') {
|
||||
var offset = 0;
|
||||
}
|
||||
if(typeof window.scrollpositions == 'undefined') { window.scrollpositions = new Object();}
|
||||
window.scrollpositions[id] = obj.offset().top - $(window).scrollTop() - offset;
|
||||
}
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· Go back to my scroll po
|
||||
·
|
||||
· @param obj: jQuery object to put in the remebered position
|
||||
· @param id: id for remembered position
|
||||
· @param animate: if we want to animate the scroll
|
||||
· @param callback: function to run when animation stops
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
function backToMyScrollPos(obj,id,animate,callback) {
|
||||
var pos = obj.offset().top-window.scrollpositions[id];
|
||||
if(animate) {
|
||||
if(typeof callback !== 'undefined'){
|
||||
$('html, body').animate({ scrollTop: pos}, 1000, 'easeOutExpo',function(){
|
||||
callback();
|
||||
});
|
||||
}
|
||||
else {
|
||||
$('html, body').animate({ scrollTop: pos }, 1000, 'easeOutExpo');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('html, body').scrollTop(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ·
|
||||
·
|
||||
· outerHTML
|
||||
·
|
||||
· · · · · · · · · · · · · */
|
||||
|
||||
jQuery.fn.outerHTML = function(s) {
|
||||
return s
|
||||
? this.before(s).remove()
|
||||
: jQuery("<p>").append(this.eq(0).clone()).html();
|
||||
};
|
1296
js/qvitter-1.js
Normal file
BIN
screenshot1.png
Normal file
After Width: | Height: | Size: 735 KiB |
BIN
screenshot2.png
Normal file
After Width: | Height: | Size: 596 KiB |
71
settings.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· ·
|
||||
· Q V I T T E R ·
|
||||
· ·
|
||||
· http://github.com/hannesmannerheim/qvitter ·
|
||||
· ·
|
||||
· ·
|
||||
· <o) ·
|
||||
· /_//// ·
|
||||
· (____/ ·
|
||||
· (o< ·
|
||||
· o> \\\\_\ ·
|
||||
· \\) \____) ·
|
||||
· ·
|
||||
· ·
|
||||
· ·
|
||||
· Qvitter 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 three of the License or (at ·
|
||||
· your option) any later version. ·
|
||||
· ·
|
||||
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||
· ·
|
||||
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
|
||||
// SITE TITLE
|
||||
$sitetitle = 'Quitter';
|
||||
|
||||
// SITE DOMAIN
|
||||
$siterootdomain = 'quitter.se'; // no http:// or https:// and no ending slash
|
||||
|
||||
// API ROOT
|
||||
$apiroot = 'http://quitter.se/api/';
|
||||
|
||||
// TIME BETWEEN POLLING
|
||||
$timebetweenpolling = 5000; // ms
|
||||
|
||||
// FORCE SSL ON AVATAR URLS AND SUCH
|
||||
$forcessl = false;
|
||||
|
||||
// USE history.pushState TO REWRITE URLS IN THE LOCATION BAR (use with mod_rewrite)
|
||||
// Try this rule in .htaccess:
|
||||
// RewriteRule ^(search/)?(notice\?q=|group/|tag/)?([a-z0-9%]+)?(/all|/subscriptions|/subscribers|/groups|/replies|/favorites)?$ /theme/quitter-theme2/qvitter/index.php [L]
|
||||
$usehistorypushstate = false;
|
||||
|
||||
// FULL PATH TO THIS QVITTER APP
|
||||
// (can be left blank, but if you're not doing mod_rewrites you need this)
|
||||
$qvitterpath = ''; // WITH trailing slash!!
|
||||
|
||||
|
||||
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||
· ·
|
||||
· (o> >o) ·
|
||||
· \\\\_\ /_//// .
|
||||
· \____) (____/ ·
|
||||
· ·
|
||||
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||
|
||||
?>
|