mirror of
https://gitlab.com/octospacc/Proxatore.git
synced 2025-06-05 17:19:18 +02:00
v0.16, 11/05
This commit is contained in:
660
LICENSE.md
Normal file
660
LICENSE.md
Normal file
@ -0,0 +1,660 @@
|
||||
# GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
<https://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 <https://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 <https://www.gnu.org/licenses/>.
|
444
Proxatore.php
444
Proxatore.php
@ -1,5 +1,31 @@
|
||||
<?php
|
||||
const APPNAME = '🎭️ Proxatore';
|
||||
/*
|
||||
* Proxatore, a content proxy for viewing and embedding media and text from various platforms.
|
||||
* Copyright (C) 2025 OctoSpacc
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*********** Configuration ***********/
|
||||
|
||||
const APP_NAME = '🎭️ Proxatore';
|
||||
const APP_DESCRIPTION = 'a content proxy for viewing and embedding media and text from various platforms.';
|
||||
|
||||
// if you make changes to the source code, please modify this to point to your modified version
|
||||
const SOURCE_CODE = 'https://hlb0.octt.eu.org/Drive/Misc/Scripts/Proxatore.php';
|
||||
|
||||
// cobalt API server URL; set to false or null or '' to avoid using cobalt
|
||||
const COBALT_API = 'http://192.168.1.125:9010/';
|
||||
|
||||
const OPTIONS_DEFAULTS = [
|
||||
@ -8,56 +34,75 @@ const OPTIONS_DEFAULTS = [
|
||||
'htmlmedia' => false,
|
||||
'relativemedia' => false,
|
||||
'mediaproxy' => false,
|
||||
'viewmode' => 'normal',
|
||||
];
|
||||
|
||||
const OPTIONS_OVERRIDES = [
|
||||
'bbs.spacc.eu.org' => [
|
||||
'embedfirst' => true,
|
||||
],
|
||||
];
|
||||
const GOOGLE_VERIFICATION = 'HjNf-db8xb7lkRNgD3Q8-qeF1lWsbxmCZptRyjLBnrI';
|
||||
const BING_VERIFICATION = '45DC0FC265FF4059D48677970BE86150';
|
||||
|
||||
/*************************************/
|
||||
|
||||
//define('SCRIPT_NAME', $_SERVER['SCRIPT_NAME'] /* '/' */);
|
||||
define('SCRIPT_NAME', ($_SERVER['SCRIPT_NAME'] === '/' ? $_SERVER['SCRIPT_NAME'] : "{$_SERVER['SCRIPT_NAME']}/"));
|
||||
define('HISTORY_FILE', './Proxatore.history.jsonl');
|
||||
|
||||
// const OPTIONS_OVERRIDES = [
|
||||
// 'bbs.spacc.eu.org' => [
|
||||
// 'embedfirst' => true,
|
||||
// ],
|
||||
// ];
|
||||
|
||||
const PLATFORMS = [
|
||||
'spaccbbs' => ['bbs.spacc.eu.org'],
|
||||
'spaccbbs' => ['bbs.spacc.eu.org'],
|
||||
'bluesky' => ['bsky.app'],
|
||||
'facebook' => ['facebook.com', 'm.facebook.com'],
|
||||
'instagram' => ['instagram.com'],
|
||||
//'juxt' => ['juxt.pretendo.network'],
|
||||
'reddit' => ['old.reddit.com', 'reddit.com'],
|
||||
'spotify' => ['open.spotify.com'],
|
||||
'telegram' => ['t.me', 'telegram.me'],
|
||||
'facebook' => ['facebook.com', 'm.facebook.com'],
|
||||
'instagram' => ['instagram.com'],
|
||||
//'juxt' => ['juxt.pretendo.network'],
|
||||
'reddit' => ['old.reddit.com', 'reddit.com'],
|
||||
'spotify' => ['open.spotify.com'],
|
||||
'telegram' => ['t.me', 'telegram.me'],
|
||||
'threads' => ['threads.net', 'threads.com'],
|
||||
'tiktok' => ['tiktok.com'],
|
||||
'twitter' => ['twitter.com'],
|
||||
'x' => ['x.com'],
|
||||
'xiaohongshu' => ['xiaohongshu.com'],
|
||||
'youtube' => ['youtube.com', 'm.youtube.com'],
|
||||
'tiktok' => ['tiktok.com'],
|
||||
'twitter' => ['twitter.com'],
|
||||
'x' => ['x.com'],
|
||||
'xiaohongshu' => ['xiaohongshu.com'],
|
||||
'youtube' => ['youtube.com', 'm.youtube.com'],
|
||||
];
|
||||
|
||||
const PLATFORMS_USERSITES = ['altervista.org', 'blogspot.com', 'wordpress.com'];
|
||||
|
||||
const PLATFORMS_ALIASES = [
|
||||
'x' => 'twitter',
|
||||
'x' => 'twitter',
|
||||
];
|
||||
|
||||
const PLATFORMS_PROXIES = [
|
||||
'bluesky' => ['fxbsky.app'],
|
||||
'instagram' => ['ddinstagram.com', 'd.ddinstagram.com', 'kkinstagram.com'],
|
||||
'instagram' => ['ddinstagram.com', 'd.ddinstagram.com', 'kkinstagram.com'],
|
||||
'threads' => ['vxthreads.net'],
|
||||
'tiktok' => ['vxtiktok.com'],
|
||||
'twitter' => ['fxtwitter.com', 'vxtwitter.com', 'fixvx.com'],
|
||||
'x' => ['fixupx.com', 'girlcockx.com', 'stupidpenisx.com'],
|
||||
'tiktok' => ['vxtiktok.com'],
|
||||
'twitter' => ['fxtwitter.com', 'vxtwitter.com', 'fixvx.com'],
|
||||
'x' => ['fixupx.com', 'girlcockx.com', 'stupidpenisx.com'],
|
||||
];
|
||||
|
||||
const PLATFORMS_REDIRECTS = [
|
||||
'vm.tiktok.com' => 'tiktok',
|
||||
//'youtu.be' => 'youtube',
|
||||
'vm.tiktok.com' => 'tiktok',
|
||||
'youtu.be' => 'youtube',
|
||||
];
|
||||
|
||||
const PLATFORMS_API = [
|
||||
'tiktok' => ['https://www.tiktok.com/player/api/v1/items?item_ids=', [
|
||||
'description' => "['items'][0]['desc']",
|
||||
'video' => "['items'][0]['video_info']['url_list'][0]",
|
||||
]],
|
||||
'spotify' => [
|
||||
'id' => '__NEXT_DATA__',
|
||||
'data' => [
|
||||
'audio' => "['props']['pageProps']['state']['data']['entity']['audioPreview']['url']",
|
||||
],
|
||||
],
|
||||
'tiktok' => [
|
||||
'url' => 'https://www.tiktok.com/player/api/v1/items?item_ids=',
|
||||
'data' => [
|
||||
'description' => "['items'][0]['desc']",
|
||||
'video' => "['items'][0]['video_info']['url_list'][0]",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
const PLATFORMS_COBALT = ['instagram'];
|
||||
@ -79,32 +124,28 @@ const PLATFORMS_PARAMS = [
|
||||
];
|
||||
|
||||
const EMBEDS = [
|
||||
'spotify' => ['open.spotify.com/embed/'],
|
||||
'reddit' => ['embed.reddit.com'],
|
||||
'spotify' => ['open.spotify.com/embed/'],
|
||||
'reddit' => ['embed.reddit.com'],
|
||||
];
|
||||
|
||||
const EMBEDS_PREFIXES_SIMPLE = [
|
||||
'tiktok' => 'www.tiktok.com/embed/v3/',
|
||||
'twitter' => 'platform.twitter.com/embed/Tweet.html?id=',
|
||||
'tiktok' => 'www.tiktok.com/embed/v3/',
|
||||
'twitter' => 'platform.twitter.com/embed/Tweet.html?id=',
|
||||
];
|
||||
|
||||
const EMBEDS_PREFIXES_PARAMS = [
|
||||
'youtube' => 'www.youtube.com/embed/[v]',
|
||||
'youtube' => 'www.youtube.com/embed/[v]',
|
||||
];
|
||||
|
||||
const EMBEDS_SUFFIXES = [
|
||||
'instagram' => '/embed/captioned/',
|
||||
'telegram' => '?embed=1&mode=tme',
|
||||
'instagram' => '/embed/captioned/',
|
||||
'telegram' => '?embed=1&mode=tme',
|
||||
];
|
||||
|
||||
define('EMBEDS_PREFIXES_FULL', [
|
||||
'facebook' => 'www.facebook.com/plugins/post.php?href=' . urlencode('https://www.facebook.com/'),
|
||||
'facebook' => 'www.facebook.com/plugins/post.php?href=' . urlencode('https://www.facebook.com/'),
|
||||
]);
|
||||
|
||||
define('APP_SLUG', explode(' ', APPNAME)[1]);
|
||||
define('SCRIPT_NAME', /* $_SERVER['SCRIPT_NAME'] . */ '/');
|
||||
define('HISTORY_FILE', './' . APP_SLUG . '.history.jsonl');
|
||||
|
||||
function normalizePlatform(string $platform): string {
|
||||
if (str_contains($platform, '.')) {
|
||||
$platform = lstrip($platform, '.', -2); //implode('.', array_slice(explode('.', $platform), -2));
|
||||
@ -121,11 +162,11 @@ function platformMapGet(string $platform, array $array): mixed {
|
||||
}
|
||||
|
||||
function lstrip(string $str, string $sub, int $num): string {
|
||||
return implode($sub, array_slice(explode($sub, $str), $num));
|
||||
return implode($sub, array_slice(explode($sub, $str), $num));
|
||||
}
|
||||
|
||||
function urlLast(string $url): string {
|
||||
return end(explode('/', trim(parse_url($url, PHP_URL_PATH), '/')));
|
||||
return end(explode('/', trim(parse_url($url, PHP_URL_PATH), '/')));
|
||||
}
|
||||
|
||||
function parseAbsoluteUrl(string $str) {
|
||||
@ -136,14 +177,18 @@ function parseAbsoluteUrl(string $str) {
|
||||
}
|
||||
|
||||
function redirectTo($url): void {
|
||||
if (!($absolute = parseAbsoluteUrl($url)) && !readProxatoreParam('history') /* && !(str_contains($url, '?proxatore-history=false') || str_contains($url, '&proxatore-history=false')) */) {
|
||||
if (!($absolute = parseAbsoluteUrl($url)) && !readProxatoreBool('history') /* && !(str_contains($url, '?proxatore-history=false') || str_contains($url, '&proxatore-history=false')) */) {
|
||||
parse_str(parse_url($url, PHP_URL_QUERY), $params);
|
||||
if (!isset($params['proxatore-history'])) {
|
||||
$url = $url . (str_contains($url, '?') ? '&' : '?') . 'proxatore-history=false';
|
||||
}
|
||||
}
|
||||
header('Location: ' . ($absolute ? '' : SCRIPT_NAME) . $url);
|
||||
die();
|
||||
// if ($_SERVER['REQUEST_METHOD'] === 'GET' || $absolute) {
|
||||
header('Location: ' . ($absolute ? '' : SCRIPT_NAME) . $url);
|
||||
// } else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// echo postRequest(SCRIPT_NAME, 'proxatore-url=' . str_replace('?', '&', $url));
|
||||
// }
|
||||
die();
|
||||
}
|
||||
|
||||
function fetchContent(string $url, int $redirects=-1): array {
|
||||
@ -185,7 +230,7 @@ function makeEmbedUrl(string $platform, string $relativeUrl): string {
|
||||
} else if (isset(EMBEDS_PREFIXES_FULL[$platform])) {
|
||||
$url = EMBEDS_PREFIXES_FULL[$platform] . urlencode($relativeUrl);
|
||||
} else {
|
||||
$url = (EMBEDS[$platform][0] ?: PLATFORMS[$platform][0] ?: PLATFORMS_PROXIES[$platform][0] ?: $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? '');
|
||||
$url = (EMBEDS[$platform][0] ?? PLATFORMS[$platform][0] ?? PLATFORMS_PROXIES[$platform][0] ?? $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? '');
|
||||
}
|
||||
return "https://{$url}";
|
||||
// switch ($platform) {
|
||||
@ -237,7 +282,7 @@ function loadHistory(): array {
|
||||
return $history;
|
||||
}
|
||||
|
||||
function saveHistory($entry): void {
|
||||
function saveHistory(array $entry): void {
|
||||
if (inPlatformArray($entry['platform'], PLATFORMS_FAKE404)) {
|
||||
$history = searchExactHistory($entry['platform'], implode('/', array_slice(explode('/', $entry['relativeurl']), -1)));
|
||||
if (sizeof($history)) {
|
||||
@ -291,8 +336,10 @@ function searchExactHistory(string $platform, string $relativeUrl): array {
|
||||
}
|
||||
|
||||
function htmldom(string $body): DOMDocument {
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTML(mb_convert_encoding($body, 'HTML-ENTITIES', 'UTF-8'));
|
||||
libxml_clear_errors();
|
||||
return $doc;
|
||||
}
|
||||
|
||||
@ -317,11 +364,12 @@ function makeResultObject(string $platform, string $relativeUrl, array $metaTags
|
||||
'locale' => $metaTags['og:locale'] ?? '',
|
||||
'type' => $metaTags['og:type'] ?? '',
|
||||
'image' => $metaTags['og:image'] ?? '',
|
||||
'video' => $metaTags['og:video'] ?: $metaTags['og:video:url'] ?: '',
|
||||
'video' => $metaTags['og:video'] ?? $metaTags['og:video:url'] ?? '',
|
||||
'videotype' => $metaTags['og:video:type'] ?? '',
|
||||
'title' => $metaTags['og:title'] ?: $metaTags['og:title'] ?: '',
|
||||
'audio' => $metaTags['og:audio'] ?? '',
|
||||
'title' => $metaTags['og:title'] ?? $metaTags['og:title'] ?? '',
|
||||
//'author' => $metaTags['og:site_name'] ?? '',
|
||||
'description' => $metaTags['og:description'] ?: $metaTags['description'] ?: '',
|
||||
'description' => $metaTags['og:description'] ?? $metaTags['description'] ?? '',
|
||||
'images' => [],
|
||||
];
|
||||
}
|
||||
@ -337,9 +385,18 @@ function makeParamsRelativeUrl(string $platform, string $url): string {
|
||||
return rtrim($url, '?&');
|
||||
}
|
||||
|
||||
function readBoolParam(string $key, $default=null, $array=null) {
|
||||
function getQueryArray(): array {
|
||||
// switch ($_SERVER['REQUEST_METHOD']) {
|
||||
// case 'GET':
|
||||
return $_GET;
|
||||
// case 'POST':
|
||||
// return $_POST;
|
||||
// }
|
||||
}
|
||||
|
||||
function readBoolParam(string $key, bool|null $default=null, array $array=null) {
|
||||
if (!$array) {
|
||||
$array = $_GET;
|
||||
$array = getQueryArray();
|
||||
}
|
||||
$value = $array[$key] ?? null;
|
||||
if ($value && $value !== '') {
|
||||
@ -349,11 +406,18 @@ function readBoolParam(string $key, $default=null, $array=null) {
|
||||
}
|
||||
}
|
||||
|
||||
function readProxatoreParam(string $key, $array=null) {
|
||||
function readProxatoreBool(string $key, array $array=null) {
|
||||
return readBoolParam("proxatore-{$key}", OPTIONS_DEFAULTS[$key], $array);
|
||||
// TODO handle domain HTTP referer overrides
|
||||
}
|
||||
|
||||
function readProxatoreParam(string $key, array $array=null) {
|
||||
if (!$array) {
|
||||
$array = getQueryArray();
|
||||
}
|
||||
return ($array["proxatore-{$key}"] ?? OPTIONS_DEFAULTS[$key] ?? null);
|
||||
}
|
||||
|
||||
function getPageData($platform, $relativeUrl) {
|
||||
if ($platform && $relativeUrl && ($data = fetchContent(makeScrapeUrl($platform, $relativeUrl)))['body']) {
|
||||
// if (!in_array($platform, PLATFORMS_TRACKING)) {
|
||||
@ -374,15 +438,19 @@ function getPageData($platform, $relativeUrl) {
|
||||
}
|
||||
}
|
||||
|
||||
function getCobaltVideo(string $url) {
|
||||
$cobaltData = json_decode(file_get_contents(COBALT_API, false, stream_context_create(['http' => [
|
||||
'header' => [
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json',
|
||||
],
|
||||
function postRequest(string $url, string $body, array $headers=null): string|false {
|
||||
return file_get_contents($url, false, stream_context_create(['http' => [
|
||||
'header' => $headers,
|
||||
'method' => 'POST',
|
||||
'content' => json_encode(['url' => $url]),
|
||||
]])));
|
||||
'content' => $body,
|
||||
]]));
|
||||
}
|
||||
|
||||
function getCobaltVideo(string $url) {
|
||||
$cobaltData = json_decode(postRequest(COBALT_API, json_encode(['url' => $url]), [
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json',
|
||||
]));
|
||||
if ($cobaltData->status === 'redirect' && strpos($cobaltData->url, '.mp4')) {
|
||||
return $cobaltData->url;
|
||||
}
|
||||
@ -393,9 +461,16 @@ function fetchPageMedia(string $url, array &$result): void {
|
||||
$relativeUrl = $result['relativeurl'];
|
||||
//if ((in_array($platform, PLATFORMS_VIDEO) && !$immediateResult['video']) || !$immediateResult['image']) {
|
||||
if ($api = platformMapGet($platform, PLATFORMS_API)) {
|
||||
$data = json_decode(fetchContent($api[0] . urlLast($relativeUrl))['body'], true);
|
||||
$json = null;
|
||||
if (isset($api['url'])) {
|
||||
$json = fetchContent($api['url'] . urlLast($relativeUrl))['body'];
|
||||
} else if (isset($api['id'])) {
|
||||
$doc = htmldom(fetchContent(makeEmbedUrl($platform, $relativeUrl))['body']);
|
||||
$json = $doc->getElementById($api['id'])->textContent;
|
||||
}
|
||||
$data = json_decode($json, true);
|
||||
$values = [];
|
||||
foreach ($api[1] as $key => $query) {
|
||||
foreach ($api['data'] as $key => $query) {
|
||||
$values[$key] = eval("return \$data{$query};");
|
||||
}
|
||||
$result = array_merge($result, $values);
|
||||
@ -418,8 +493,8 @@ function fetchPageMedia(string $url, array &$result): void {
|
||||
}
|
||||
|
||||
function getYoutubeStreamUrl(string $relativeUrl): string {
|
||||
if ($video = preg_replace("/[^A-Za-z0-9-_]/", '', escapeshellarg(substr($relativeUrl, -11)))) {
|
||||
return trim(shell_exec("yt-dlp -g '{$video}'"));
|
||||
if ($video = preg_replace("/[^A-Za-z0-9-_]/", '', substr($relativeUrl, -11))) {
|
||||
return trim(shell_exec("yt-dlp -g 'https://youtube.com/watch?v={$video}'"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,6 +522,10 @@ function handleApiRequest(array $segments): void {
|
||||
die();
|
||||
}
|
||||
|
||||
function linkifyUrls(string $text): string {
|
||||
return preg_replace('/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', '<a href="$0" target="_blank" rel="noopener nofollow" title="$0">$0</a>', $text);
|
||||
}
|
||||
|
||||
function iframeHtml($result): void { ?>
|
||||
<?php if (inPlatformArray($result['platform'], PLATFORMS_ORDERED)): ?>
|
||||
<div>
|
||||
@ -457,10 +536,10 @@ function iframeHtml($result): void { ?>
|
||||
<iframe src="<?= htmlspecialchars(makeEmbedUrl($result['platform'], $result['relativeurl'])) ?>"></iframe>
|
||||
<?php }
|
||||
|
||||
$path = $_SERVER['REQUEST_URI']; //parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
$path = lstrip($_SERVER['REQUEST_URI'], SCRIPT_NAME, 1); //$_SERVER['REQUEST_URI']; //parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
$immediateResult = null;
|
||||
|
||||
if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !== '') {
|
||||
if (isset(getQueryArray()['proxatore-search']) && ($search = getQueryArray()['proxatore-search']) !== '') {
|
||||
if ($url = parseAbsoluteUrl($search)) {
|
||||
return redirectTo($url);
|
||||
} else {
|
||||
@ -474,9 +553,9 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
}
|
||||
|
||||
$segments = explode('/', $path);
|
||||
if (SCRIPT_NAME !== '/') {
|
||||
array_shift($segments);
|
||||
}
|
||||
// if (SCRIPT_NAME !== '/') {
|
||||
// array_shift($segments);
|
||||
// }
|
||||
|
||||
$platform = null;
|
||||
$upstream = $segments[0] ?? null;
|
||||
@ -498,13 +577,15 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
return redirectTo($platform . '/' . $relativeUrl);
|
||||
}
|
||||
}
|
||||
unset($platform);
|
||||
//unset($platform);
|
||||
$platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$platform && isset(PLATFORMS_REDIRECTS[$upstream])) {
|
||||
// TODO: only strip query params for platforms that don't need them
|
||||
$relativeUrl = trim(parse_url(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], PHP_URL_PATH), '/');
|
||||
// // TODO: only strip query params for platforms that don't need them
|
||||
//$relativeUrl = trim(parse_url(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], PHP_URL_PATH), '/');
|
||||
$relativeUrl = trim(lstrip(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], '/', 3), '/');
|
||||
$platform = PLATFORMS_REDIRECTS[$upstream];
|
||||
return redirectTo("{$platform}/{$relativeUrl}");
|
||||
} else if (!$platform) {
|
||||
@ -520,8 +601,8 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
if ($data = getPageData($platform, $relativeUrl)) {
|
||||
http_response_code($data['code']);
|
||||
$immediateResult = $data['result'];
|
||||
if ($immediateResult['video'] && $immediateResult['videotype'] === 'text/html' && readProxatoreParam('htmlmedia')) {
|
||||
$proxy = ((readProxatoreParam('mediaproxy') || $_GET['proxatore-mediaproxy'] === 'video') ? 'file' : '');
|
||||
if ($immediateResult['video'] && $immediateResult['videotype'] === 'text/html' && readProxatoreBool('htmlmedia')) {
|
||||
$proxy = ((readProxatoreBool('mediaproxy') || getQueryArray()['proxatore-mediaproxy'] === 'video') ? 'file' : '');
|
||||
$immediateResult['video'] = SCRIPT_NAME . "__{$proxy}proxy__/{$platform}/{$immediateResult['video']}";
|
||||
$immediateResult['videotype'] = 'video/mp4';
|
||||
}
|
||||
@ -530,16 +611,16 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
//if ($immediateResult['title'] || $immediateResult['description']) {
|
||||
// saveHistory($immediateResult);
|
||||
//} else
|
||||
if ($content['code'] >= 400) {
|
||||
if ($data['code'] >= 400) {
|
||||
$searchResults = searchExactHistory($platform, $immediateResult['relativeurl']);
|
||||
if (sizeof($searchResults)) {
|
||||
$immediateResult = $searchResults[0];
|
||||
}
|
||||
} else if (readProxatoreParam('history')) {
|
||||
} else if (readProxatoreBool('history')) {
|
||||
saveHistory($immediateResult);
|
||||
}
|
||||
$immediateResult['description'] = preg_replace('/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', '<a href="$0" target="_blank" rel="noopener nofollow" title="$0">$0</a>', $immediateResult['description']);
|
||||
if (readProxatoreParam('relativemedia')) {
|
||||
$immediateResult['description'] = linkifyUrls($immediateResult['description']);
|
||||
if (readProxatoreBool('relativemedia')) {
|
||||
$count = 0;
|
||||
foreach (['video', 'image'] as $type) {
|
||||
if ($immediateResult[$type]) {
|
||||
@ -549,7 +630,7 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
}
|
||||
}
|
||||
$searchResults = [$immediateResult];
|
||||
} else {
|
||||
} else if ($path) {
|
||||
http_response_code(404);
|
||||
}
|
||||
}
|
||||
@ -559,22 +640,28 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title><?= APPNAME ?></title>
|
||||
<meta name="description" content="<?= htmlspecialchars($immediateResult['description'] ?? 'Content Proxy for viewing media and text from various platforms.') ?>" />
|
||||
<meta property="og:title" content="<?= htmlspecialchars($immediateResult['title'] ?? APPNAME) ?>" />
|
||||
<meta property="og:description" content="<?= htmlspecialchars($immediateResult['description'] ?? 'View content from supported platforms.') ?>" />
|
||||
<title><?= APP_NAME ?></title>
|
||||
<meta name="description" content="<?= htmlspecialchars($immediateResult['description'] ?? ucfirst(APP_DESCRIPTION)) ?>" />
|
||||
<meta property="og:title" content="<?= htmlspecialchars($immediateResult['title'] ?? APP_NAME) ?>" />
|
||||
<meta property="og:description" content="<?= htmlspecialchars($immediateResult['description'] ?? ucfirst(APP_DESCRIPTION)) ?>" />
|
||||
<!--<meta property="og:locale" content="<?= htmlspecialchars($immediateResult['locale'] ?? '') ?>" />-->
|
||||
<meta property="og:type" content="<?= htmlspecialchars($immediateResult['type'] ?? '') ?>" />
|
||||
<meta property="og:image" content="<?= htmlspecialchars($immediateResult['image'] ?? '') ?>" />
|
||||
<?php if ($immediateResult['video']): ?>
|
||||
<?php if (isset($immediateResult['video'])): ?>
|
||||
<meta property="og:video" content="<?= htmlspecialchars($immediateResult['video']) ?>" />
|
||||
<meta property="og:video:type" content="<?= htmlspecialchars($immediateResult['videotype'] ?: 'video/mp4') ?>" />
|
||||
<?php endif; ?>
|
||||
<meta property="og:site_name" content="<?= APPNAME . ' ' . $immediateResult['platform'] ?>" />
|
||||
<?php if (isset($immediateResult['audio'])): ?>
|
||||
<meta property="og:audio" content="<?= htmlspecialchars($immediateResult['audio']) ?>" />
|
||||
<meta property="og:audio:type" content="audio/mpeg" />
|
||||
<?php endif; ?>
|
||||
<meta property="og:site_name" content="<?= APP_NAME . ' ' . ($immediateResult['platform'] ?? '') ?>" />
|
||||
<meta property="og:url" content="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
||||
<link rel="canonical" href="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
||||
<!--<link rel="alternate" type="application/json+oembed" href="" />
|
||||
<link rel="alternate" type="application/xml+oembed" href="" />-->
|
||||
<meta name="google-site-verification" content="<?= GOOGLE_VERIFICATION ?>" />
|
||||
<meta name="msvalidate.01" content="<?= BING_VERIFICATION ?>" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -596,14 +683,19 @@ iframe {
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
width: 90%;
|
||||
margin: 20px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
body.normal .container {
|
||||
width: 90%;
|
||||
margin: 20px;
|
||||
}
|
||||
body.embed .container {
|
||||
width: 100%;
|
||||
}
|
||||
a.button {
|
||||
padding: 0.5em;
|
||||
border: 1px solid gray;
|
||||
@ -638,11 +730,13 @@ h2 {
|
||||
.history-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
}
|
||||
body.normal .history-item {
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
.history-item:hover {
|
||||
body.normal .history-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.history-item img, .history-item video {
|
||||
@ -677,6 +771,12 @@ img[src=""], video[src=""] {
|
||||
video:not(video[src=""]) + .img {
|
||||
max-width: 45% !important;
|
||||
}
|
||||
.description {
|
||||
white-space: preserve-breaks;
|
||||
border-left: 2px solid black;
|
||||
padding: 1em;
|
||||
word-break: break-word;
|
||||
}
|
||||
.history-item strong {
|
||||
font-size: 1.2rem;
|
||||
color: #1c1e21;
|
||||
@ -779,81 +879,113 @@ ul.platforms a {
|
||||
} */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1><a href="<?= SCRIPT_NAME ?>"><?= APPNAME; ?></a></h1>
|
||||
<form method="get" action="<?= SCRIPT_NAME ?>">
|
||||
<body class="<?= readProxatoreParam('viewmode'); ?>">
|
||||
<div class="container">
|
||||
<?php if (readProxatoreParam('viewmode') !== 'embed'): ?>
|
||||
<h1><a href="<?= SCRIPT_NAME ?>"><?= APP_NAME; ?></a></h1>
|
||||
<form method="GET" action="<?= SCRIPT_NAME ?>">
|
||||
<div class="search-bar">
|
||||
<input type="text" required="required" name="proxatore-search" placeholder="Search or Input URL" value="<?= htmlspecialchars($_GET['proxatore-search'] ?: makeCanonicalUrl($immediateResult) ?: '') ?>">
|
||||
<input type="text" required="required" name="proxatore-search" placeholder="Search or Input URL" value="<?= htmlspecialchars(getQueryArray()['proxatore-search'] ?? makeCanonicalUrl($immediateResult) ?: '') ?>">
|
||||
<button type="submit">Go 💣️</button>
|
||||
</div>
|
||||
<details style="margin-bottom: 20px;">
|
||||
<summary>Options</summary>
|
||||
<ul>
|
||||
<li><label><input type="checkbox" name="proxatore-history" value="false" <?php if ($_GET['proxatore-history'] === 'false') echo 'checked="true"' ?> /> Incognito Mode (don't save query to global cache/history)</label></li>
|
||||
<li><label><input type="checkbox" name="proxatore-history" value="false" <?php if (!readProxatoreBool('history')) echo 'checked="checked"' ?> /> Incognito Mode (don't save query to global cache/history)</label></li>
|
||||
</ul>
|
||||
</details>
|
||||
</form>
|
||||
<?php if (!isset($searchResults)) {
|
||||
$platforms = '';
|
||||
$searchPrefix = (SCRIPT_NAME . '?proxatore-search=');
|
||||
echo '<p>Supported Platforms:</p><ul class="platforms">';
|
||||
foreach (array_keys(PLATFORMS) as $platform) {
|
||||
//echo ((isset(PLATFORMS_ALIASES[$platform])) ? "/" : "</li><li>") . $platform;
|
||||
$platforms .= ((isset(PLATFORMS_ALIASES[$platform])) ? '/' : "</a></li><li><a href='{$searchPrefix}\"platform\":\"{$platform}\"'>") . $platform;
|
||||
}
|
||||
foreach (PLATFORMS_USERSITES as $platform) {
|
||||
$platforms .= "</a></li><li><a href='{$searchPrefix}.{$platform}\",\"relativeurl\"'>{$platform}";
|
||||
}
|
||||
echo substr($platforms, strlen('</a></li>')) . '</a></li></ul>';
|
||||
// echo '<details><summary>Query API</summary><ul>
|
||||
// <li>/?<code>proxatore-search=</code>{search term} — Make a full-text search or load a given URL</li>
|
||||
// <li>...?<code>proxatore-history=</code>{true,false} — Specify if a given query must be stored in the global search history (default: true)</li>
|
||||
// </ul></details>';
|
||||
echo '<p>Made with 🕸️ and 🧨 by <a href="https://hub.octt.eu.org">OctoSpacc</a>.
|
||||
<small>Source Code: <a href="https://hlb0.octt.eu.org/Drive/Misc/Scripts/Proxatore.php">Proxatore.php</a>.</small>
|
||||
</p>';
|
||||
} ?>
|
||||
<?php if (isset($immediateResult) && readProxatoreParam('embedfirst')) iframeHtml($immediateResult); ?>
|
||||
<?php if (isset($searchResults)): ?>
|
||||
<?php if (!isset($immediateResult)): ?>
|
||||
<h3>Search results:</h3>
|
||||
<?php if (!sizeof($searchResults)): ?>
|
||||
<p>Nothing was found.</p>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!isset($searchResults)) {
|
||||
$platforms = '';
|
||||
$searchPrefix = (SCRIPT_NAME . '?proxatore-search=');
|
||||
echo '<p>Supported Platforms:</p><ul class="platforms">';
|
||||
foreach (array_keys(PLATFORMS) as $platform) {
|
||||
//echo ((isset(PLATFORMS_ALIASES[$platform])) ? "/" : "</li><li>") . $platform;
|
||||
$platforms .= ((isset(PLATFORMS_ALIASES[$platform])) ? '/' : "</a></li><li><a href='{$searchPrefix}\"platform\":\"{$platform}\"'>") . $platform;
|
||||
}
|
||||
foreach (PLATFORMS_USERSITES as $platform) {
|
||||
$platforms .= "</a></li><li><a href='{$searchPrefix}.{$platform}\",\"relativeurl\"'>{$platform}";
|
||||
}
|
||||
echo substr($platforms, strlen('</a></li>')) . '</a></li></ul>';
|
||||
// echo '<details><summary>Query string API</summary><ul>
|
||||
// <li>/?<code>proxatore-search=</code>{search term} — Make a full-text search or load a given URL</li>
|
||||
// <li>...?<code>proxatore-history=</code>{true,false} — Specify if a given query must be stored in the global search history (default: true)</li>
|
||||
// </ul></details>';
|
||||
echo '<details><summary>Help & Info</summary>
|
||||
<h3>What is this?</h3><p>
|
||||
'.APP_NAME.' is '.APP_DESCRIPTION.'
|
||||
<br />It allows you to bypass ratelimits and georestrictions when accessing contents from many specific Internet platforms,
|
||||
and to view them with a clean and streamlined interface, that works well on both modern systems and old browsers or slow connections.
|
||||
<br />Additionally, it allows you to share links between social media platforms, ensuring link previews, which are often blocked by competitors, always display correctly.
|
||||
</p>
|
||||
<h3>How to self-host?</h3><p>
|
||||
This software is free and open-source, and you can host it on your own server, for either private or public use.
|
||||
</p>
|
||||
<h4>Base requirements</h4><dl>
|
||||
<dt>A web server with PHP</dt>
|
||||
<dd>(Currently only tested on nginx with PHP 8.2 and IIS with PHP 8.3, as of May 2025.)</dd>
|
||||
<dt><code>curl</code> and <code>mbstring</code> PHP extensions</dt>
|
||||
<dd>The program requires these PHP extensions to be installed and enabled on the server to work.</dd>
|
||||
</dl>
|
||||
<h4>Optional requirements</h4><dl>
|
||||
<dt>A dedicated domain name</dt>
|
||||
<dd>To host the program properly, instead of in a subpath.</dd>
|
||||
<dt><a href="https://github.com/yt-dlp/yt-dlp" target="_blank">yt-dlp</a> on your server</dt>
|
||||
<dd>To stream YouTube videos in MP4 format.</dd>
|
||||
<dt>A <a href="https://github.com/imputnet/cobalt">cobalt</a> API server</dt>
|
||||
<dd>To have a fallback for access to media files for most platforms.</dd>
|
||||
</dl>
|
||||
</details>';
|
||||
echo '<p>Made with 🕸️ and 🧨 by <a href="https://hub.octt.eu.org">OctoSpacc</a>.
|
||||
<br /><small>Licensed under <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank">AGPLv3</a>. Source Code: <a href="' . SOURCE_CODE . '">Proxatore.php</a>.</small>
|
||||
</p>';
|
||||
} ?>
|
||||
<?php if (isset($immediateResult) && readProxatoreBool('embedfirst') && readProxatoreParam('viewmode') !== 'embed') iframeHtml($immediateResult); ?>
|
||||
<?php if (isset($searchResults)): ?>
|
||||
<?php if (!isset($immediateResult)): ?>
|
||||
<h3>Search results:</h3>
|
||||
<?php if (!sizeof($searchResults)): ?>
|
||||
<p>Nothing was found.</p>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($searchResults as $item): ?>
|
||||
<div class="history-item <?php
|
||||
similar_text($item['title'], $item['description'], $percent);
|
||||
if ($percent > 90) echo 'ellipsize';
|
||||
?>">
|
||||
<p class="title">
|
||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime']) ?> --></small>
|
||||
</p>
|
||||
<div style="text-align: center;">
|
||||
<?php if ($item['video'] /* $item['video'] && $item['videotype'] !== 'text/html' */): ?>
|
||||
<video src="<?= htmlspecialchars($item['platform'] === 'youtube' ? (SCRIPT_NAME . '__proxy__/youtube/' . $immediateResult['video']) : ($item['video'] ?? '')) ?>" controls="controls"></video>
|
||||
<?php endif; ?>
|
||||
<?php foreach (array_merge([$item['image']], $item['images']) as $image): ?>
|
||||
<a class="img" href="<?= htmlspecialchars($image ?? '') ?>" target="_blank" rel="noopener nofollow"><img src="<?= htmlspecialchars($image ?? '') ?>" onerror="this.hidden=true" /></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime']) ?> --></small>
|
||||
</p>
|
||||
<p style="white-space: preserve-breaks; border-left: 2px solid black; padding: 1em; word-break: break-word;"><?= /*htmlspecialchars*/($item['description']) ?></p>
|
||||
<p>
|
||||
<a class="button block" href="<?= htmlspecialchars(makeCanonicalUrl($item)) ?>" target="_blank" rel="noopener nofollow">Original on <code><?= htmlspecialchars(PLATFORMS[$item['platform']][0] ?: $item['platform']) ?>/<?= htmlspecialchars($item['relativeurl']) ?></code></a>
|
||||
<a class="button block" href="<?= htmlspecialchars(SCRIPT_NAME . $item['platform'] . '/' . $item['relativeurl']) ?>"><?= APPNAME ?> Permalink</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($immediateResult) && !readProxatoreParam('embedfirst')) iframeHtml($immediateResult); ?>
|
||||
</div>
|
||||
<?php foreach ($searchResults as $item): ?>
|
||||
<div class="history-item <?php
|
||||
similar_text($item['title'], $item['description'], $percent);
|
||||
if ($percent > 90) echo 'ellipsize';
|
||||
?>">
|
||||
<p class="title">
|
||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime'] ?? '') ?> --></small>
|
||||
</p>
|
||||
<div style="text-align: center;">
|
||||
<?php if ($item['video'] /* $item['video'] && $item['videotype'] !== 'text/html' */): ?>
|
||||
<video src="<?= htmlspecialchars($item['platform'] === 'youtube' ? (SCRIPT_NAME . '__proxy__/youtube/' . $immediateResult['video']) : ($item['video'] ?? '')) ?>" controls="controls"></video>
|
||||
<?php endif; ?>
|
||||
<?php if ($item['audio']): ?>
|
||||
<audio src="<?= htmlspecialchars($item['audio']) ?>" controls="controls"></audio>
|
||||
<?php endif; ?>
|
||||
<?php foreach (array_merge([$item['image']], $item['images']) as $image): ?>
|
||||
<a class="img" href="<?= htmlspecialchars($image ?? '') ?>" target="_blank" rel="noopener nofollow"><img src="<?= htmlspecialchars($image ?? '') ?>" onerror="this.hidden=true" /></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime'] ?? '') ?> --></small>
|
||||
</p>
|
||||
<?php if ($item['description']): ?><p class="description"><?= /*htmlspecialchars*/($item['description']) ?></p><?php endif; ?>
|
||||
<p>
|
||||
<a class="button block" href="<?= htmlspecialchars(makeCanonicalUrl($item)) ?>" target="_blank" rel="noopener nofollow">Original on <code><?= htmlspecialchars(PLATFORMS[$item['platform']][0] ?: $item['platform']) ?>/<?= htmlspecialchars($item['relativeurl']) ?></code></a>
|
||||
<a class="button block" href="<?= htmlspecialchars(SCRIPT_NAME . $item['platform'] . '/' . $item['relativeurl']) ?>" <?php if (readProxatoreParam('viewmode') === 'embed') echo 'target="_blank"'; ?> >
|
||||
<?= readProxatoreParam('viewmode') === 'embed' ? ('Powered by ' . APP_NAME) : (APP_NAME . ' Permalink') ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($immediateResult) && !readProxatoreBool('embedfirst') && readProxatoreParam('viewmode') !== 'embed') iframeHtml($immediateResult); ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user