Conflicts:
	htroot/yacysearchitem.java
	source/net/yacy/cora/federate/solr/responsewriter/YJsonResponseWriter.java
	source/net/yacy/search/schema/CollectionConfiguration.java
	source/net/yacy/server/serverObjects.java
pull/39/head
luccioman 9 years ago
commit 6e1959f469

@ -16,7 +16,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/commons-logging-1.2.jar"/>
<classpathentry kind="lib" path="lib/J7Zip-modified.jar"/>
<classpathentry kind="lib" path="lib/webcat-swf-0.1.jar"/>
<classpathentry kind="lib" path="lib/commons-jxpath-1.3.jar"/>
<classpathentry kind="lib" path="lib/jsch-0.1.53.jar"/>
<classpathentry kind="lib" path="lib/jakarta-oro-2.0.8.jar"/>
@ -24,7 +23,7 @@
<classpathentry kind="lib" path="lib/json-simple-1.1.1.jar"/>
<classpathentry kind="lib" path="lib/xercesImpl.jar"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="lib" path="lib/commons-compress-1.11.jar"/>
<classpathentry kind="lib" path="lib/commons-compress-1.12.jar"/>
<classpathentry kind="lib" path="lib/commons-lang-2.6.jar"/>
<classpathentry kind="lib" path="lib/jaudiotagger-2.0.4-20111207.115108-15.jar"/>
<classpathentry kind="lib" path="lib/commons-codec-1.10.jar"/>
@ -39,29 +38,29 @@
<classpathentry kind="lib" path="lib/spatial4j-0.5.jar"/>
<classpathentry kind="lib" path="lib/zookeeper-3.4.6.jar"/>
<classpathentry kind="lib" path="lib/org.restlet.jar"/>
<classpathentry kind="lib" path="lib/fontbox-2.0.2.jar"/>
<classpathentry kind="lib" path="lib/pdfbox-2.0.2.jar"/>
<classpathentry kind="lib" path="lib/fontbox-2.0.3.jar"/>
<classpathentry kind="lib" path="lib/pdfbox-2.0.3.jar"/>
<classpathentry kind="lib" path="lib/bcmail-jdk15-1.46.jar"/>
<classpathentry kind="lib" path="lib/bcprov-jdk15-1.46.jar"/>
<classpathentry kind="lib" path="lib/poi-3.14-20160307.jar"/>
<classpathentry kind="lib" path="lib/poi-scratchpad-3.14-20160307.jar"/>
<classpathentry kind="lib" path="lib/poi-3.15.jar"/>
<classpathentry kind="lib" path="lib/poi-scratchpad-3.15.jar"/>
<classpathentry kind="lib" path="lib/commons-io-2.5.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-1.7.21.jar"/>
<classpathentry kind="lib" path="lib/chardet.jar"/>
<classpathentry kind="lib" path="lib/jetty-client-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-continuation-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-deploy-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-http-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-io-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-jmx-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-proxy-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-security-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-server-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-servlet-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-servlets-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-util-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-webapp-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-xml-9.2.17.v20160517.jar"/>
<classpathentry kind="lib" path="lib/jetty-client-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-continuation-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-deploy-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-http-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-io-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-jmx-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-proxy-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-security-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-server-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-servlet-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-servlets-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-util-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-webapp-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/jetty-xml-9.2.18.v20160721.jar"/>
<classpathentry kind="lib" path="lib/httpclient-4.5.2.jar"/>
<classpathentry kind="lib" path="lib/httpmime-4.5.2.jar"/>
<classpathentry kind="lib" path="lib/noggit-0.6.jar"/>
@ -100,6 +99,5 @@
<classpathentry kind="lib" path="lib/imageio-bmp-3.2.1.jar"/>
<classpathentry kind="lib" path="lib/jsonic-1.2.0.jar"/>
<classpathentry kind="lib" path="lib/langdetect.jar"/>
<classpathentry kind="lib" path="lib/xliff-core-1.2-1.1.jar"/>
<classpathentry kind="output" path="gen"/>
</classpath>

@ -0,0 +1,2 @@
MAVEN_CUSTOM_OPTS=-f libbuild/pom.xml -DskipTests=true
PORT=8090

3
.gitignore vendored

@ -16,4 +16,5 @@ RELEASE/
/winDATA.bkp/
/DATA.cloud/
yacy.log
/target/
/target/
/test/DATA/

@ -0,0 +1,91 @@
# Yacy on Heroku
YaCy can be deployed on Heroku platform in various ways. There are currently limitations which make this deployment option better suited for demonstration or testing purposes.
## Limitations
### Ephemeral file system
Each Heroku container instance (aka ["dyno"](https://devcenter.heroku.com/articles/dynos#dynos)) file system is [ephemeral](https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem) : all files are discarded each time the "dyno" is restarted (at least automatically once a day by the platform).
This is not a problem for applications storing their persistent data in an external cloud datastore. But YaCy is currently designed to use the local file system. So beware that when running YaCy on Heroku, all your settings and indexed data will be lost once a day.
### Build version
YaCy main git history is too large to be pushed on Heroku (more than 300MB Heroku "slug" limit), but it is normally used to produce the revision number suffix added to main version. So when building on Heroku platform, YaCy version in /Status.html will always appears with a default revision number (for example 1.91/9000).
## Deploy with the button
- Click on the 'Deploy to Heroku' button on the main YaCy [README.md](README.md).
- Log in with your Heroku account or create one.
- A preconfigured deploy page is proposed (configuration comes from the [app.json](app.json) file).
- Enter the name of your application (don't let Heroku choose a default one).
- Edit the configuration variable `YACY_PUBLIC_URL` : fill it with an URL like `your_app_name.herokuapp.com`, with `your_app_name` replaced with the name you choosed.
If you ignore this step, YaCy will run, but in junior mode : it will not be able to be reached by other peers and will not contribute to the global indexing.
- Edit the configuration variable `YACY_INIT_ADMIN_PASSWORD` : fill it with your custom admin password encoded with YaCy (you can get this encoded value by running a local YaCy peer, setting your custom admin password in /ConfigAccounts_p.html, and retrieving it in DATA/SETTINGS/yacy.conf at key `adminAccountBase64MD5`).
- Click on the deploy button.
- Heroku now build YaCy from sources.
- If everything went fine, you can open YaCy search page with the `View` button
## Deploy from command line
Here are some brief instructions to deploy YaCy on Heroku from command line. More detailed explanations can be found on related [Heroku documentation](https://devcenter.heroku.com/articles/getting-started-with-java#introduction).
- Install the Heroku Toolbelt
- Get YaCy sources from git as a zip archive, or be sure to remove the .git directory (if you cloned from git, the .git directory will be far too large and later you will not be able to push sources to Heroku).
- Optional steps (deploy locally to check everything is fine) :
- build with maven : `mvn clean dependency:list install -DskipTests=true -f libbuild/pom.xml`
- run locally : `heroku local`
- check everything works fine at http://localhost:8090
- stop the local YaCy
- Log in on heroku : `heroku login`
- Create an app on heroku : `heroku create [your_app_name]`
- Initialize a git repository : `git init`
- Add remote heroku git repository for this deployment : `heroku git:remote -a your_app_name`
- Set the `MAVEN_CUSTOM_OPTS` config var : `heroku config:set MAVEN_CUSTOM_OPTS="-f libbuild/pom.xml -DskipTests=true"`
- Set the `YACY_INIT_ADMIN_PASSWORD` config var : `heroku config:set YACY_INIT_ADMIN_PASSWORD="MD5:[your_encoded_password]"`
- Set the `YACY_PUBLIC_URL` config var : `heroku config:set YACY_PUBLIC_URL="[your_app_name].herokuapp.com"`
- Add files to git index : `git add .`
- Commit : `git commit`
- Push to heroku : `git push heroku master`
- Open app on your browser : `heroku open -a your_app_name`
## Deploy with GitHub account
- Log in on [Heroku](https://www.heroku.com/)
- Click the 'New > Create new app' button
- Eventually choose your app name and your region, then click 'Create App'
- Go to the 'Settings' tab
- Click the 'Reveal Config Vars' button, and add vars `MAVEN_CUSTOM_OPTS`, `YACY_INIT_ADMIN_PASSWORD`, `YACY_PUBLIC_URL` with values filled as described in the previous paragraph
- Go to the 'Deploy' tab
- Choose 'GitHub' deployment method
- Enter your GitHub account information
- Select your YaCy repository clone and 'Connect'
- Choose either automatic or manual deploy, and click the deploy button
- If everything went fine, you can open YaCy search page with the 'View' button
## Technical details
### Heroku specific configuration files :
- [app.json](app.json) : used when deploying with the button
- [.env](.env) : set up environment variables for local heroku run
- [Procfile](Procfile) : contain main process description used to launch YaCy
### Custom maven options
With any of the deployment methods described, setting the option `-f libbuild/pom.xml -DskipTests=true` in the `MAVEN_CUSTOM_OPTS` environment variable is the minimum required for a successfull build and deploy. If not set, build will fail because missing dependent submodules from libbuild directory.
What'smore, the only way for other YaCy peers to reach a peer running on Heroku is to use the "dyno" public URL (in the form of your_app_name.herokuapp.com). This is why the configuration variable `YACY_PUBLIC_URL` as to be set, or else your YaCy peer will run in "junior" mode. This variable is used in the Procfile to customize the `staticIP` initial property in the [yacy.init](defaults/yacy.init) file at launch.
### HTTP local port
On heroku platform, you can not choose your application binding port. It is set by Heroku in the `PORT` environment variable, and at startup, the application has to bind to this port within 90 seconds. So YaCy has to bind to this port each time the "dyno" is started, and thus can not rely on its normal configuration file. This is done with the JVM system property `net.yacy.server.localPort` set in Procfile.
### Administrator password
If you wish to use YaCy administration features, you have to set an admin password, and authenticate with it. To generate the encoded password hash set in the config var `YACY_INIT_ADMIN_PASSWORD`, you can proceed as follow :
- either run a local YaCy peer, set your custom admin password in /ConfigAccounts_p.html, and retrieve it in DATA/SETTINGS/yacy.conf at key `adminAccountBase64MD5`
- OR run this command in YaCy source directory :
- `java -classpath target/classes:lib/* net.yacy.cora.order.Digest -strfhex "admin:The YaCy access is limited to administrators. If you don't know the password, you can change it using <yacy-home>/bin/passwd.sh <new-password>:[your_password]"`

@ -0,0 +1 @@
web: if [ "" != "$YACY_INIT_ADMIN_PASSWORD" ] ; then sed -i "/adminAccountBase64MD5=/c\adminAccountBase64MD5=$YACY_INIT_ADMIN_PASSWORD" defaults/yacy.init;fi && sed -i "/port = 8090/c\port = 80" defaults/yacy.init && if [ "" != "$YACY_PUBLIC_URL" ] ; then sed -i "/staticIP=/c\staticIP=$YACY_PUBLIC_URL" defaults/yacy.init;fi && java $JAVA_OPTS -Dnet.yacy.server.localPort="$PORT" -classpath target/classes:lib/* net.yacy.yacy

@ -1,4 +1,10 @@
== WHAT IS THIS? ==
# YaCy
[![Deploy to Docker Cloud](https://files.cloud.docker.com/images/deploy-to-dockercloud.svg)](https://cloud.docker.com/stack/deploy/?repo=https://github.com/yacy/yacy_search_server/tree/master/docker)
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
## What is this?
YaCy is a search engine software. It takes a new approach to search
because it does not use a central server. Instead, its search results
come from a network of independent peers. In such a distributed network,
@ -34,24 +40,27 @@ set up their own node. More users are leading to higher index capacity
and better distributed indexing performance.
== LICENSE ==
## License
YaCy is published under the GPL v2
The source code is inside the release package (see /source and /htroot).
== WHERE IS THE DOCUMENTATION? ==
## Where is the documentation?
Documentation can be found at:
(Home Page) http://yacy.net/
(German Forum) http://forum.yacy.de/
(Wiki:de) http://www.yacy-websuche.de/wiki/index.php/De:Start
(Wiki:en) http://www.yacy-websearch.net/wiki/index.php/En:Start
(Tutorial Videos) http://yacy.net/en/Tutorials.html and http://yacy.net/de/Lehrfilme.html
- (Home Page) http://yacy.net/
- (German Forum) http://forum.yacy.de/
- (Wiki:de) http://www.yacy-websuche.de/wiki/index.php/De:Start
- (Wiki:en) http://www.yacy-websearch.net/wiki/index.php/En:Start
- (Tutorial Videos) http://yacy.net/en/Tutorials.html and http://yacy.net/de/Lehrfilme.html
Every of these locations has a (YaCy) search functionality which combines
all these locations into one search result.
== DEPENDENCIES? WHAT OTHER SOFTWARE DO I NEED? ==
## Dependencies? What other software do I need?
You need java 1.7 or later to run YaCy, nothing else.
Please download it from http://www.java.com
@ -62,7 +71,8 @@ NO OTHER SOFTWARE IS REQUIRED!
(you don't need apache, tomcat or mysql or whatever)
== HOW DO I START THIS SOFTWARE? ==
## How do I start this software?
Startup and Shutdown of YaCy:
- on GNU/Linux and OpenBSD:
@ -78,7 +88,8 @@ please use the Mac Application and start or stop it like any
other Mac Application (doubleclick to start)
== HOW DO I USE THIS SOFTWARE, WHERE IS THE ADMINISTRATION INTERFACE? ==
## How do I use this software, where is the administration interface?
YaCy is a build on a web server. After you started YaCy,
start your browser and open
@ -87,7 +98,8 @@ start your browser and open
There you can see your personal search and administration interface.
== WHAT IF I INSTALL YACY (HEADLESS) ON A SERVER ==
## What if I install YaCy (headless) on a server?
You can do that but YaCy authorizes users automatically if they
access the server from the localhost. After about 10 minutes a random
password is generated and then it is not possible to log in from
@ -99,22 +111,37 @@ http://<remote-server-address>:8090/ConfigAccounts_p.html
and set an administration account.
== CAN I RUN YACY IN A VIRTUAL MACHINE OR A CONTAINER ==
## Can I run YaCy in a virtual machine or a container?
YaCy runs fine in virtual machines managed by software such as VirtualBox or VMware.
Container technology may be more flexible and lightweight and also works fine with YaCy.
More details for YaCy with Docker [[docker/Readme.md|here]].
These technologies can either be deployed locally, on remote machines you own, or in the 'cloud'. Decide what fits the most your privacy requirements.
### Docker
Deploy easily YaCy on a Docker cloud provider of your choice (can be a machine you own) with the deploy button at the top of this page.
More details for YaCy with Docker in [docker/Readme.md](docker/Readme.md).
### Heroku
Deploy easily on [Heroku](https://www.heroku.com/) PaaS (Platform as a service) provider using the deploy button at the top.
More details for YaCy on Heroku in [Heroku.md](Heroku.md).
## Port 8090 is bad, people are not allowed to access that port
== PORT 8090 IS BAD, PEOPLE ARE NOT ALLOWED TO ACCESS THAT PORT ==
You can forward port 80 to 8090 with iptables:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8090
On some operation systems, you must first enable access to the ports you are using like:
iptables -I INPUT -m tcp -p tcp --dport 8090 -j ACCEPT
== HOW CAN I SCALE THIS; HOW MUCH RAM IS NEEDED; DISK SPACE? ==
## How can I scale this; how much ram is needed; disk space?
YaCy can scale up to many millions of web pages in your own search index.
The default assignment of RAM is 600MB which is assigned to the java
process but not permanently used by it. The GC process will free the memory
@ -129,22 +156,23 @@ space i.e. setting the htcache space to a different size; to do that
open http://localhost:8090/ConfigHTCache_p.html and set a new size.
## Join the development!
== JOIN THE DEVELOPMENT! ==
YaCy was created with the help of many. About 30 programmers have helped,
a list of some of them can be seen here: http://yacy.net/en/Join.html
Please join us!
== HOW TO GET THE SOURCE CODE AND HOW TO COMPILE YACY YOURSELF? ==
## How to get the source code and how to compile YaCy yourself?
The source code is inside every YaCy release. You can also get YaCy
from https://github.com/yacy/yacy_search_server
Please clone our code and help with development!
The code is licensed under the GPL v2.
Compiling YaCy:
- you need java 1.7 and ant
- just compile: "ant clean all" - then you can "./startYACY.sh"
- you need Java 1.7 or later and [Apache Ant](http://ant.apache.org/)
- just compile: "ant clean all" - then you can "./startYACY.sh" or "./startYACY.bat"
- create a release tarball: "ant dist"
- create a Mac OS release: "ant distMacApp" (works only on a Mac)
- create a debian release: "ant deb"
@ -152,8 +180,8 @@ Compiling YaCy:
because the servlet pages are not compiled by the eclipse build process
after the dist prodecure, the release can be found in the RELEASE subdirectory
## Are there any APIs or how can I attach software at YaCy?
== ARE THERE ANY APIs OR HOW CAN I ATTACH SOFTWARE AT YACY? ==
There are many interfaces build-in in YaCy and they are all based on http/xml and
http/json. You can discover these interfaces if you notice the orange "API" icon in
the upper right of some web pages in the YaCy web interface. Just click on it and
@ -163,8 +191,8 @@ A different approach is the usage of the shell script provided in the /bin
subdirectory. The just call also the web interface pages. By cloning some of those
scripts you can create more shell api access methods yourself easily.
## Contact
== CONTACT ==
Our primary point of contact is the german forum at http://forum.yacy.net
There is also an english forum at http://www.yacy-forum.org
We encourage you to start a YaCy forum in your own language.

@ -7,7 +7,7 @@
<key>CFBundleDisplayName</key>
<string>YaCy</string>
<key>CFBundleShortVersionString</key>
<string>1.82</string>
<string>1.90</string>
<key>CFBundleGetInfoString</key>
<string>Peer-to-Peer Search Engine</string>
<key>NSHumanReadableCopyright</key>
@ -15,11 +15,11 @@
<key>CFBundleIdentifier</key>
<string>net.yacy.yacy</string>
<key>CFBundleVersion</key>
<string>1.82</string>
<string>1.90</string>
<key>CFBundleAllowMixedLocalizations</key>
<string>true</string>
<key>CFBundleExecutable</key>
<string>JavaAppLauncher</string>
<string>startYACYMacOS.sh</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundlePackageType</key>
@ -30,14 +30,5 @@
<string>6.0</string>
<key>CFBundleIconFile</key>
<string>YaCy_2013_Icon.icns</string>
<key>JVMMainClassName</key>
<string>net.yacy.yacy</string>
<key>JVMOptions</key>
<array>
</array>
<key>JVMArguments</key>
<array>
</array>
</dict>
</plist>

@ -0,0 +1,8 @@
#!/usr/bin/env sh
# Launcher for YaCy in a MacOS bundle :
# rely on the generic startYACY.sh, but specifies the user home relative path for YaCy data
# This data directory is set in conforming to OS X File System Programming Guide
# see : https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html
"`dirname $0`"/startYACY.sh -s "'Library/Application Support/net.yacy.YaCy'"

@ -0,0 +1,28 @@
{
"name": "YaCy",
"description": "Decentralized Web Search",
"keywords": [
"yacy",
"search",
"p2p",
"decentralized",
"java"
],
"website": "http://yacy.net",
"repository": "https://github.com/yacy/yacy_search_server",
"logo": "http://yacy.net/material/YaCyLogo2011.svg",
"env": {
"YACY_INIT_ADMIN_PASSWORD": {
"description": "Administrator initial password : please fill with a Base64 MD5 value",
"required": false
},
"YACY_PUBLIC_URL": {
"description": "External URL used by other peers to reach yours, required to run in 'Senior' mode. You chould set it with [your_app_name].herokuapp.com.",
"required": false
},
"MAVEN_CUSTOM_OPTS": {
"description": "Custom options required for maven build on Heroku.",
"value": "-f libbuild/pom.xml -DskipTests=true"
}
}
}

@ -167,13 +167,13 @@
<pathelement location="${lib}/common-io-3.2.1.jar" />
<pathelement location="${lib}/common-lang-3.2.1.jar" />
<pathelement location="${lib}/commons-codec-1.10.jar" />
<pathelement location="${lib}/commons-compress-1.11.jar" />
<pathelement location="${lib}/commons-compress-1.12.jar" />
<pathelement location="${lib}/commons-fileupload-1.3.2.jar" />
<pathelement location="${lib}/commons-io-2.5.jar" />
<pathelement location="${lib}/commons-jxpath-1.3.jar" />
<pathelement location="${lib}/commons-lang-2.6.jar" />
<pathelement location="${lib}/commons-logging-1.2.jar" />
<pathelement location="${lib}/fontbox-2.0.2.jar" />
<pathelement location="${lib}/fontbox-2.0.3.jar" />
<pathelement location="${lib}/guava-18.0.jar" />
<pathelement location="${lib}/htmllexer.jar" />
<pathelement location="${lib}/httpclient-4.5.2.jar" />
@ -190,20 +190,20 @@
<pathelement location="${lib}/javax.servlet-api-3.1.0.jar" />
<pathelement location="${lib}/jcifs-1.3.17.jar" />
<pathelement location="${lib}/jcl-over-slf4j-1.7.21.jar" />
<pathelement location="${lib}/jetty-client-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-continuation-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-deploy-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-http-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-io-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-jmx-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-proxy-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-security-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-server-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-servlet-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-servlets-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-util-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-webapp-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-xml-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jetty-client-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-continuation-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-deploy-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-http-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-io-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-jmx-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-proxy-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-security-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-server-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-servlet-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-servlets-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-util-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-webapp-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jetty-xml-9.2.18.v20160721.jar" />
<pathelement location="${lib}/jsch-0.1.53.jar" />
<pathelement location="${lib}/json-simple-1.1.1.jar" />
<pathelement location="${lib}/jsoup-1.9.2.jar" />
@ -229,20 +229,18 @@
<pathelement location="${lib}/metadata-extractor-2.9.1.jar" />
<pathelement location="${lib}/noggit-0.5.jar" />
<pathelement location="${lib}/org.restlet.jar" />
<pathelement location="${lib}/pdfbox-2.0.2.jar" />
<pathelement location="${lib}/poi-3.14-20160307.jar" />
<pathelement location="${lib}/poi-scratchpad-3.14-20160307.jar" />
<pathelement location="${lib}/pdfbox-2.0.3.jar" />
<pathelement location="${lib}/poi-3.15.jar" />
<pathelement location="${lib}/poi-scratchpad-3.15.jar" />
<pathelement location="${lib}/slf4j-api-1.7.21.jar" />
<pathelement location="${lib}/slf4j-jdk14-1.7.21.jar" />
<pathelement location="${lib}/solr-core-5.5.2.jar" />
<pathelement location="${lib}/solr-solrj-5.5.2.jar" />
<pathelement location="${lib}/spatial4j-0.5.jar" />
<pathelement location="${lib}/stax2-api_3.1.4.jar" />
<pathelement location="${lib}/webcat-swf-0.1.jar" />
<pathelement location="${lib}/weupnp-0.1.4.jar" />
<pathelement location="${lib}/woodstox-core-asl-4.4.1.jar" />
<pathelement location="${lib}/xercesImpl.jar" />
<pathelement location="${lib}/xliff-core-1.2-1.1.jar" />
<pathelement location="${lib}/xml-apis.jar" />
<pathelement location="${lib}/xmpcore-5.1.2.jar" />
<pathelement location="${lib}/zookeeper-3.4.6.jar" />
@ -764,9 +762,10 @@
<fileset dir="${addon}/YaCy.app"></fileset>
</copy>
<copy file="${addon}/YaCy.app/Contents/Info.plist" tofile="${release_mac}/YaCy.app/Contents/Info.plist" filtering="true" overwrite="true" />
<move file="${release_main}" tofile="${release_mac}/YaCy.app/Contents/Resources/Java" verbose="false" />
<chmod file="${release_mac}/YaCy.app/Contents/MacOS/JavaAppLauncher" perm="755"/>
<chmod file="${release_mac}/YaCy.app/Contents/Resources/Java/startYACY.sh" perm="755"/>
<move file="${release_main}" tofile="${release_mac}/YaCy.app/Contents/MacOS" verbose="false" />
<!-- startYACY.sh and startYACYMacOS.sh will be the main entry points : we set permissions to make it executable files -->
<chmod file="${release_mac}/YaCy.app/Contents/MacOS/startYACYMacOS.sh" perm="755"/>
<chmod file="${release_mac}/YaCy.app/Contents/MacOS/startYACY.sh" perm="755"/>
<exec executable="hdiutil">
<arg line="create -srcfolder ${release_mac}/YaCy.app ${release}/yacy_v${releaseVersion}_${DSTAMP}_${releaseNr}.dmg"/>
</exec>

@ -35,7 +35,7 @@
that you fully re-index after changing this setting as it can
affect both how text is indexed and queried.
-->
<luceneMatchVersion>5.2.0</luceneMatchVersion>
<luceneMatchVersion>5.5.0</luceneMatchVersion>
<!-- <lib/> directives can be used to instruct Solr to load any Jars
identified and use them to resolve any "plugins" specified in

@ -286,8 +286,9 @@ parser.pdf.individualpages.key=page
promoteSearchPageGreeting = Web Search by the People, for the People
# if the following property is set to true, the network name is used as greeting
promoteSearchPageGreeting.useNetworkName = false
# the following attributes can be used to define a custom image and home page on the search page
# the following attributes can be used to define a custom image, alternative text and home page on the search page
promoteSearchPageGreeting.homepage = http://yacy.net
promoteSearchPageGreeting.imageAlt = YaCy project web site
promoteSearchPageGreeting.largeImage = /env/grafics/YaCyLogo_120ppi.png
promoteSearchPageGreeting.smallImage = /env/grafics/YaCyLogo_60ppi.png
@ -1130,10 +1131,6 @@ memory.disabledDHT = false
# wether using standard memory strategy - or try generation memory strategy
memory.standardStrategy = true
# setting if execution of CGI files is allowed or not
cgi.allow = false
cgi.suffixes = cgi,pl
# content integration settings
content.phpbb3.urlstub = http://<mydomain>/
content.phpbb3.dbtype = mysql

@ -18,6 +18,10 @@ WORKDIR /opt
# - Compile with ant
# - remove unnecessary and size consuming .git directory
# - remove ant and git packages
# Possible alternative : copy directly your current sources an remove git clone command from the following RUN
# COPY . /opt/yacy_search_server/
RUN apt-get update && \
apt-get install -yq ant git && \
git clone https://github.com/yacy/yacy_search_server.git && \
@ -30,14 +34,17 @@ RUN apt-get update && \
# Set initial admin password : "docker" (encoded with custom yacy md5 function net.yacy.cora.order.Digest.encodeMD5Hex())
RUN sed -i "/adminAccountBase64MD5=/c\adminAccountBase64MD5=MD5:e672161ffdce91be4678605f4f4e6786" /opt/yacy_search_server/defaults/yacy.init
# Intially enable HTTPS : this is the most secure option for remote administrator authentication
RUN sed -i "/server.https=false/c\server.https=true" /opt/yacy_search_server/defaults/yacy.init
# Create user and group yacy : this user will be used to run YaCy main process
RUN adduser --system --group --no-create-home --disabled-password yacy
# Set ownership of yacy install directory to yacy user/group
RUN chown yacy:yacy -R /opt/yacy_search_server
# Expose port 8090
EXPOSE 8090
# Expose HTTP and HTTPS default ports
EXPOSE 8090 8443
# Set data volume : yacy data and configuration will persist aven after container stop or destruction
VOLUME ["/opt/yacy_search_server/DATA"]

@ -51,6 +51,10 @@ WORKDIR /opt
# - compile with apache ant
# - remove unnecessary and size consuming .git directory
# - delete git package and ant binary install
# Possible alternative : copy directly your current sources an remove git clone command from the following RUN
# COPY . /opt/yacy_search_server/
RUN apk update && \
apk add --no-cache git && \
git clone https://github.com/yacy/yacy_search_server.git && \
@ -62,14 +66,17 @@ RUN apk update && \
# Set initial admin password : "docker" (encoded with custom yacy md5 function net.yacy.cora.order.Digest.encodeMD5Hex())
RUN sed -i "/adminAccountBase64MD5=/c\adminAccountBase64MD5=MD5:e672161ffdce91be4678605f4f4e6786" /opt/yacy_search_server/defaults/yacy.init
# Intially enable HTTPS : this is the most secure option for remote administrator authentication
RUN sed -i "/server.https=false/c\server.https=true" /opt/yacy_search_server/defaults/yacy.init
# Create user and group yacy : this user will be used to run YaCy main process
RUN addgroup yacy && adduser -S -G yacy -H -D yacy
# Set ownership of yacy install directory to yacy user/group
RUN chown yacy:yacy -R /opt/yacy_search_server
# Expose port 8090
EXPOSE 8090
# Expose HTTP and HTTPS default ports
EXPOSE 8090 8443
# Set data volume : yacy data and configuration will persist aven after container stop or destruction
VOLUME ["/opt/yacy_search_server/DATA"]

@ -1,7 +1,5 @@
# Yacy Docker image from latest sources
[![Deploy to Docker Cloud](https://files.cloud.docker.com/images/deploy-to-dockercloud.svg)](https://cloud.docker.com/stack/deploy/?repo=https://github.com/luccioman/yacy_search_server/tree/docker/docker)
## Supported tags and respective Dockerfiles
* latest (Dockerfile)
@ -20,6 +18,11 @@ Using yacy_search_server/docker/Dockerfile :
cd yacy_search_server/docker
docker build .
To build the Alpine variant :
cd yacy_search_server/docker
docker build -f Dockerfile.alpine .
## Image variants
`luccioman/yacy:latest`
@ -51,12 +54,12 @@ You can retrieve the container IP address with `docker inspect`.
#### Easier to handle
docker run --name yacy -p 8090:8090 --log-opt max-size=100m --log-opt max-file=2 luccioman/yacy
docker run --name yacy -p 8090:8090 -p 8443:8443 --log-opt max-size=200m --log-opt max-file=2 luccioman/yacy
##### Options detail
* --name : allow easier management of your container (without it, docker automatically generate a new name at each startup).
* -p : map host port and container port, allowing web interface access through the usual http://localhost:8090.
* -p 8090:8090 -p 8443:8443 : map host ports to YaCy container ports, allowing web interface access through the usual http://localhost:8090 and https://localhost:8443 (you can set a different mapping, for example -p 443:8443 if you prefer to use the default HTTPS port on your host)
* --log-opt max-size : limit maximum docker log file size for this container
* --log-opt max-file : limit number of docker rotated log files for this container
@ -78,9 +81,47 @@ Note that you can list all docker volumes with :
docker volume ls
#### As background process
#### Start as background process
docker run -d luccioman/yacy
### HTTPS support
This images are default configured with HTTPS enabled, and use a default certificate stored in defaults/freeworldKeystore. You should use your own certificate. In order to do it, you can proceed as follow.
#### Self-signed certificate
A self-signed certificate will provide encrypted communications with your YaCy server, but browsers will still complain about an invalid security certificate with the error "SEC_ERROR_UNKNOWN_ISSUER". If it is sufficient for you, you can permanently add and exception to your browser.
This kind of certificate can be generated and added to your YaCy Docker container with the following :
keytool -keystore /var/lib/docker/volumes/[your_yacy_volume]/_data/SETTINGS/yacykeystore -genkey -keyalg RSA -alias yacycert
Then edit YaCy config file. For example with the nano text editor :
nano /var/lib/docker/volumes/[your_yacy_volume]/_data/SETTINGS/yacy.conf
And configure the keyStoreXXXX properties accordingly :
keyStore=/opt/yacy_search_server/DATA/SETTINGS/yacykeystore
keyStorePassword=yourpassword
#### Import an existing certificate:
Importing a certificate validated by a certification authority (CA) will ensure you have full HTTPS support with no security errors when accessing your YaCy peer. You can import an existing certificate in pkcs12 format.
First copy it to the YaCy Docker container volume :
cp [yourStore].pkcs12 /var/lib/docker/volumes/[your_yacy_volume]/_data/SETTINGS/[yourStore].pkcs12
Then edit YaCy config file. For example with the nano text editor :
nano /var/lib/docker/volumes/[your_yacy_volume]/_data/SETTINGS/yacy.conf
And configure the pkcs12XXX properties accordingly :
pkcs12ImportFile=/opt/yacy_search_server/DATA/SETTINGS/[yourStore].pkcs12
pkcs12ImportPwd=yourpassword
### Next starts
@ -111,7 +152,7 @@ OR
Create new container based on pulled image, using volume data from old container :
docker create --name [tmp-container_name] -p 8090:8090 --volumes-from=[container_name] luccioman/yacy:latest
docker create --name [tmp-container_name] -p 8090:8090 -p 8443:8443 --volumes-from=[container_name] --log-opt max-size=100m --log-opt max-file=2 luccioman/yacy:latest
Stop old container :

@ -2,5 +2,6 @@ yacy:
image: 'luccioman/yacy:latest'
ports:
- '8090:8090'
- '8443:8443'
restart: on-failure
autoredeploy: true

@ -1,5 +1,4 @@
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.crawler.data.CrawlProfile.CrawlAttribute;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverObjects;

@ -80,7 +80,7 @@
</fieldset>
</form>
<form action="yacy/list.html" method="get" accept-charset="UTF-8">
<form action="api/blacklists_p.txt" method="get" accept-charset="UTF-8">
<fieldset>
<legend>plain text file:</legend>
Here you can export a blacklist as a regular text file with one blacklist entry per line.

@ -33,14 +33,15 @@
<li>
<img src="env/grafics/ok.png" height="16" width="16" alt="ok" />&nbsp;Select a language for the interface:<br />
<fieldset>
<input type="radio" name="language" value="default" id="lang_en" onchange="this.form.submit()" #(lang_en)#::checked="checked"#(/lang_en)# /><label for="lang_en">English</label>
<input type="radio" name="language" value="de" id="lang_de" onchange="this.form.submit()" #(lang_de)#::checked="checked"#(/lang_de)# /><label for="lang_de">Deutsch</label>&nbsp;
<input type="radio" name="language" value="fr" id="lang_fr" onchange="this.form.submit()" #(lang_fr)#::checked="checked"#(/lang_fr)# /><label for="lang_fr">Fran&ccedil;ais</label>&nbsp;
<input type="radio" name="language" value="cn" id="lang_cn" onchange="this.form.submit()" #(lang_cn)#::checked="checked"#(/lang_cn)# /><label for="lang_cn">&#27721;&#35821;/&#28450;&#35486</label>
<input type="radio" name="language" value="ru" id="lang_ru" onchange="this.form.submit()" #(lang_ru)#::checked="checked"#(/lang_ru)# /><label for="lang_ru">&#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;</label>
<input type="radio" name="language" value="uk" id="lang_uk" onchange="this.form.submit()" #(lang_uk)#::checked="checked"#(/lang_uk)# /><label for="lang_uk">&#1059;&#1082;&#1088;&#1072;&#1111;&#1085;&#1089;&#1100;&#1082;&#1072;</label>
<input type="radio" name="language" value="hi" id="lang_hi" onchange="this.form.submit()" #(lang_hi)#::checked="checked"#(/lang_hi)# /><label for="lang_hi">&#2361;&#2367;&#2344;&#2381;&#2342;&#2368;</label>
<input type="radio" name="language" value="ja" id="lang_ja" onchange="this.form.submit()" #(lang_ja)#::checked="checked"#(/lang_ja)# /><label for="lang_ja">&#26085;&#26412;&#35486;</label>
<input type="radio" name="language" value="browser" id="lang_browser" onchange="this.form.submit()" #(lang_browser)#::checked="checked"#(/lang_browser)# /><label for="lang_browser">Browser</label>&nbsp;
<input type="radio" name="language" value="default" id="lang_en" onchange="this.form.submit()" #(lang_en)#::checked="checked"#(/lang_en)# /><label for="lang_en" class="#[active_en]#">English</label>&nbsp;
<input type="radio" name="language" value="de" id="lang_de" onchange="this.form.submit()" #(lang_de)#::checked="checked"#(/lang_de)# /><label class="#[active_de]#" for="lang_de">Deutsch</label>&nbsp;
<input type="radio" name="language" value="fr" id="lang_fr" onchange="this.form.submit()" #(lang_fr)#::checked="checked"#(/lang_fr)# /><label class="#[active_fr]#" for="lang_fr">Fran&ccedil;ais</label>&nbsp;
<input type="radio" name="language" value="cn" id="lang_cn" onchange="this.form.submit()" #(lang_cn)#::checked="checked"#(/lang_cn)# /><label class="#[active_cn]#" for="lang_cn">&#27721;&#35821;/&#28450;&#35486</label>
<input type="radio" name="language" value="ru" id="lang_ru" onchange="this.form.submit()" #(lang_ru)#::checked="checked"#(/lang_ru)# /><label class="#[active_ru]#" for="lang_ru">&#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;</label>
<input type="radio" name="language" value="uk" id="lang_uk" onchange="this.form.submit()" #(lang_uk)#::checked="checked"#(/lang_uk)# /><label class="#[active_uk]#" for="lang_uk">&#1059;&#1082;&#1088;&#1072;&#1111;&#1085;&#1089;&#1100;&#1082;&#1072;</label>
<input type="radio" name="language" value="hi" id="lang_hi" onchange="this.form.submit()" #(lang_hi)#::checked="checked"#(/lang_hi)# /><label class="#[active_hi]#" for="lang_hi">&#2361;&#2367;&#2344;&#2381;&#2342;&#2368;</label>
<input type="radio" name="language" value="ja" id="lang_ja" onchange="this.form.submit()" #(lang_ja)#::checked="checked"#(/lang_ja)# /><label class="#[active_ja]#" for="lang_ja">&#26085;&#26412;&#35486;</label>
</fieldset>
</li>
<!-- take care that no other items are changed, but also change the former if no js is enabled -->
@ -90,7 +91,7 @@
<dl>
<dt><label for="port">Peer Port: </label></dt>
<dd>
<input type="text" name="port" id="port" value="#[defaultPort]#" size="5" maxlength="5" />&nbsp;&nbsp;&nbsp;
<input type="text" name="port" id="port" value="#[defaultPort]#" size="5" maxlength="5" #(hasSystemDefinedPort)#::disabled="disabled"#(/hasSystemDefinedPort)#/> #(hasSystemDefinedPort)#::(Set by system property '#[systemProperty]#')#(/hasSystemDefinedPort)#&nbsp;&nbsp;&nbsp;
<input type="checkbox" name="withssl" id="withssl" #(withsslenabled)#::checked="checked"#(/withsslenabled)#>with SSL (https enabled#(withsslenabled)#:: on port <a href="Settings_p.html?page=ProxyAccess">#[sslport]#</a>#(/withsslenabled)#)
</dd>
#(upnp)#::<dt>

@ -31,11 +31,13 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;
import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.data.Translator;
import net.yacy.data.WorkTables;
import net.yacy.http.YaCyHttpServer;
import net.yacy.kelondro.workflow.InstantBusyThread;
@ -63,7 +65,7 @@ public class ConfigBasic {
final Switchboard sb = (Switchboard) env;
final serverObjects prop = new serverObjects();
final File langPath = new File(sb.getAppPath("locale.source", "locales").getAbsolutePath());
String lang = env.getConfig("locale.language", "default");
String lang = env.getConfig("locale.language", "browser");
final int authentication = sb.adminAuthenticated(header);
if (authentication < 2) {
@ -131,7 +133,7 @@ public class ConfigBasic {
// check port and ssl connection
final boolean reconnect;
if (!(env.getConfigLong("port", port) == port) || env.getConfigBool("server.https", false) != ssl) {
if (!(env.getLocalPort() == port) || env.getConfigBool("server.https", false) != ssl) {
// validate port
final YaCyHttpServer theServerCore = env.getHttpServer();
env.setConfig("port", port);
@ -266,21 +268,46 @@ public class ConfigBasic {
// set default values
prop.putHTML("defaultName", sb.peers.mySeed().getName());
prop.put("hasSystemDefinedPort", env.getLocalPortSystemProperty() != null ? 1 : 0);
prop.put("hasSystemDefinedPort_systemProperty", serverSwitch.LOCAL_PORT_SYSTEM_PROPERTY);
prop.put("defaultPort", env.getLocalPort());
prop.put("withsslenabled", env.getConfigBool("server.https", false) ? 1 : 0);
lang = env.getConfig("locale.language", "default"); // re-assign lang, may have changed
prop.put("lang_browser", "0"); // for client browser language dependent
prop.put("lang_de", "0");
prop.put("lang_fr", "0");
prop.put("lang_cn", "0");
prop.put("lang_ru", "0");
prop.put("lang_uk", "0");
prop.put("lang_en", "0");
prop.put("lang_jp", "0");
prop.put("lang_ja", "0");
if ("default".equals(lang)) {
prop.put("lang_en", "1");
} else {
prop.put("lang_" + lang, "1");
}
// set label class (green background) for active translation
if (lang.equals("browser")) {
List<String> l = Translator.activeTranslations();
prop.put("active_cn", l.contains("cn") ? "label-success" : "");
prop.put("active_de", l.contains("de") ? "label-success" : "");
prop.put("active_fr", l.contains("fr") ? "label-success" : "");
prop.put("active_hi", l.contains("hi") ? "label-success" : "");
prop.put("active_ja", l.contains("ja") ? "label-success" : "");
prop.put("active_ru", l.contains("ru") ? "label-success" : "");
prop.put("active_uk", l.contains("uk") ? "label-success" : "");
prop.put("active_en", "label-success");
} else {
prop.put("active_de", "");
prop.put("active_fr", "");
prop.put("active_hi", "");
prop.put("active_cn", "");
prop.put("active_ru", "");
prop.put("active_uk", "");
prop.put("active_en", "");
prop.put("active_ja", "");
}
return prop;
}
}

@ -81,7 +81,7 @@ public class ConfigLanguage_p {
* read from the language directory. This is very important to prevent
* directory traversal attacks!
*/
if (langFiles.contains(selectedLanguage) || selectedLanguage.startsWith("default")) {
if (langFiles.contains(selectedLanguage) || selectedLanguage.startsWith("default") || selectedLanguage.startsWith("browser")) {
new TranslatorXliff().changeLang(env, langPath, selectedLanguage);
}
@ -142,27 +142,28 @@ public class ConfigLanguage_p {
final Map<String, String> langNames = Translator.langMap(env);
//virtual entry
prop.put("langlist_0_file", "default");
prop.put("langlist_0_name", ((langNames.get("default") == null) ? "default" : langNames.get("default")));
prop.put("langlist_0_file", "browser");
prop.put("langlist_0_name", ((langNames.get("browser") == null) ? "browser" : langNames.get("browser")));
prop.put("langlist_0_selected", "selected=\"selected\"");
prop.put("langlist_1_file", "default");
prop.put("langlist_1_name", ((langNames.get("default") == null) ? "default" : langNames.get("default")));
int count = 0;
for (final String langFile : langFiles) {
//+1 because of the virtual entry "default" at top
int count = 2; //+2 because of the virtual entry "browser" and "default" at top
for (final String langFile : langFiles) {
final String langKey = langFile.substring(0, langFile.length() -4);
final String langName = langNames.get(langKey);
prop.put("langlist_" + (count + 1) + "_file", langFile);
prop.put("langlist_" + (count + 1) + "_name", ((langName == null) ? langKey : langName));
prop.put("langlist_" + (count) + "_file", langFile);
prop.put("langlist_" + (count) + "_name", ((langName == null) ? langKey : langName));
if(env.getConfig("locale.language", "default").equals(langKey)) {
prop.put("langlist_" + (count + 1) + "_selected", "selected=\"selected\"");
prop.put("langlist_" + (count) + "_selected", "selected=\"selected\"");
prop.put("langlist_0_selected", " "); // reset Default
} else {
prop.put("langlist_" + (count + 1) + "_selected", " ");
prop.put("langlist_" + (count) + "_selected", " ");
}
count++;
}
prop.put("langlist", (count + 1));
prop.put("langlist", (count));
//is done by Translationtemplate
//langName = (String) langNames.get(env.getConfig("locale.language", "default"));

@ -30,6 +30,9 @@
<dt>URL of a Large Corporate Image</dt>
<dd><input type="text" name="promoteSearchPageGreeting.largeImage" value="#[promoteSearchPageGreeting.largeImage]#" size="60" /></dd>
<dt>Alternative text for Corporate Images</dt>
<dd><input type="text" name="promoteSearchPageGreeting.imageAlt" value="#[promoteSearchPageGreeting.imageAlt]#" size="60" /></dd>
<dt>Enable Search for Everyone?</dt>
<dd>
<input type="radio" name="publicSearchpage" value="true" #(publicSearchpage)#::checked="checked"#(/publicSearchpage)# />Search is available for everyone&nbsp;
@ -146,7 +149,7 @@
</pre></fieldset>
This would look like:
<iframe name="target"
src="http://#[myPreviewAddress]#/index.html?display=2&amp;resource=local&amp;focus=0"
src="#[myPreviewProtocol]#://#[myPreviewAddress]#/index.html?display=2&amp;resource=local&amp;focus=0"
width="100%"
height="410"
frameborder="0"
@ -169,7 +172,7 @@
</pre></fieldset>
This would look like:
<iframe name="target2"
src="http://#[myPreviewAddress]#/yacysearch.html?display=2&amp;resource=local&amp;focus=0"
src="#[myPreviewProtocol]#://#[myPreviewAddress]#/yacysearch.html?display=2&amp;resource=local&amp;focus=0"
width="100%"
height="180"
frameborder="0"
@ -193,7 +196,7 @@
</pre></fieldset>
This would look like:
<iframe name="target3"
src="http://#[myPreviewAddress]#/yacyinteractive.html?display=2&amp;focus=0"
src="#[myPreviewProtocol]#://#[myPreviewAddress]#/yacyinteractive.html?display=2&amp;focus=0"
width="100%"
height="180"
frameborder="0"

@ -33,6 +33,8 @@ import java.net.MalformedURLException;
import java.util.Properties;
import net.yacy.cora.document.id.DigestURL;
import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.data.WorkTables;
@ -79,6 +81,7 @@ public class ConfigPortal {
sb.setConfig(SwitchboardConstants.GREETING_HOMEPAGE, post.get(SwitchboardConstants.GREETING_HOMEPAGE, ""));
sb.setConfig(SwitchboardConstants.GREETING_LARGE_IMAGE, post.get(SwitchboardConstants.GREETING_LARGE_IMAGE, ""));
sb.setConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, post.get(SwitchboardConstants.GREETING_SMALL_IMAGE, ""));
sb.setConfig(SwitchboardConstants.GREETING_IMAGE_ALT, post.get(SwitchboardConstants.GREETING_IMAGE_ALT, ""));
sb.setConfig(SwitchboardConstants.SEARCH_TARGET_DEFAULT, post.get("target", "_self"));
sb.setConfig(SwitchboardConstants.SEARCH_TARGET_SPECIAL, post.get("target_special", "_self"));
sb.setConfig(SwitchboardConstants.SEARCH_TARGET_SPECIAL_PATTERN, post.get("target_special_pattern", "_self"));
@ -137,6 +140,7 @@ public class ConfigPortal {
sb.setConfig(SwitchboardConstants.GREETING_HOMEPAGE, config.getProperty(SwitchboardConstants.GREETING_HOMEPAGE,"http://yacy.net"));
sb.setConfig(SwitchboardConstants.GREETING_LARGE_IMAGE, config.getProperty(SwitchboardConstants.GREETING_LARGE_IMAGE,"env/grafics/YaCyLogo_120ppi.png"));
sb.setConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, config.getProperty(SwitchboardConstants.GREETING_SMALL_IMAGE,"env/grafics/YaCyLogo_60ppi.png"));
sb.setConfig(SwitchboardConstants.GREETING_IMAGE_ALT, config.getProperty(SwitchboardConstants.GREETING_IMAGE_ALT,"YaCy project web site"));
sb.setConfig(SwitchboardConstants.BROWSER_POP_UP_PAGE, config.getProperty(SwitchboardConstants.BROWSER_POP_UP_PAGE,"Status.html"));
sb.setConfig(SwitchboardConstants.INDEX_FORWARD, config.getProperty(SwitchboardConstants.INDEX_FORWARD,""));
HTTPDFileHandler.indexForward = "";
@ -163,6 +167,7 @@ public class ConfigPortal {
prop.putHTML(SwitchboardConstants.GREETING_HOMEPAGE, sb.getConfig(SwitchboardConstants.GREETING_HOMEPAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_LARGE_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_LARGE_IMAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_SMALL_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_IMAGE_ALT, sb.getConfig(SwitchboardConstants.GREETING_IMAGE_ALT, ""));
prop.putHTML(SwitchboardConstants.INDEX_FORWARD, sb.getConfig(SwitchboardConstants.INDEX_FORWARD, ""));
prop.put("publicTopmenu", sb.getConfigBool("publicTopmenu", false) ? 1 : 0);
prop.put(SwitchboardConstants.PUBLIC_SEARCHPAGE, sb.getConfigBool(SwitchboardConstants.PUBLIC_SEARCHPAGE, false) ? 1 : 0);
@ -224,19 +229,30 @@ public class ConfigPortal {
prop.put("target_selected_special_searchresult", "searchresult".equals(target_special) ? 1 : 0);
prop.put("target_special_pattern", sb.getConfig(SwitchboardConstants.SEARCH_TARGET_SPECIAL_PATTERN, ""));
/* Addresse used in code template */
/* Address used in code template */
String myaddress = (sb.peers == null) || sb.peers.mySeed() == null || sb.peers.mySeed().getIP() == null ? null : sb.peers.mySeed().getPublicAddress(sb.peers.mySeed().getIP());
if (myaddress == null) {
myaddress = "localhost:" + sb.getLocalPort();
}
prop.put("myaddress", myaddress);
/* Adress used to display iframe preview : no need to use public adress when coming from local */
String myPreviewAddress = myaddress;
if(header.accessFromLocalhost()) {
myPreviewAddress = "localhost:" + sb.getLocalPort();
/* Address used to generate the preview frames : let's use the adress and port as requested. (Same behavior as opensearchdescription.java) */
String myPreviewAddress = header.get(HeaderFramework.HOST); // returns host:port (if not default http/https ports)
String myPreviewProtocol = "http";
if (myPreviewAddress == null) {
myPreviewAddress = Domains.LOCALHOST + ":" + sb.getConfig("port", "8090");
} else {
final String sslport = ":" + sb.getConfig("port.ssl", "8443");
if (myPreviewAddress.endsWith(sslport)) { // connection on ssl port, use https protocol
myPreviewProtocol = "https";
}
}
/* YaCyDefaultServelt should have filled this custom header, making sure we know here wether original request is http or https
* (when default ports (80 and 443) are used, there is no way to distinguish the two schemes relying only on the Host header) */
myPreviewProtocol = header.get(HeaderFramework.X_YACY_REQUEST_SCHEME, myPreviewProtocol);
prop.put("myPreviewAddress", myPreviewAddress);
prop.put("myPreviewProtocol", myPreviewProtocol);
return prop;
}

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html>
<html>
<head>
<title>YaCy '#[clientname]#': Search Page</title>
#%env/templates/metas.template%#
@ -40,7 +40,7 @@
<span class="icon-bar"></span>
</button>
<div class="forceNoExternalIcon navbar-brand" id="navbar-brand" href="#" style="position:absolute;top:-6px;display:inline;white-space:nowrap;">
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle">&nbsp;<span id="greeting"></span>
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" alt="#[promoteSearchPageGreeting.imageAlt]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle"/>&nbsp;<span id="greeting"></span>
</div>
</div>
<div class="navbar-collapse collapse">
@ -49,7 +49,7 @@
<a href="#" data-toggle="dropdown" class="dropdown-toggle">Search Interfaces<b class="caret"></b></a>
</li>
<li id="header_help" class="dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle"><span class="glyphicon glyphicon-question-sign"></span></a>
<a href="#" data-toggle="dropdown" class="dropdown-toggle" aria-label="Help" role="button"><span class="glyphicon glyphicon-question-sign"></span></a>
</li>
<li id="header_administration">
<button class="btn btn-default navbar-btn"><span class="glyphicon glyphicon-cog"></span> Administration &raquo;</button>
@ -73,16 +73,16 @@
<td>
<div style="padding-left:15px; padding-bottom:10px; width: 100%;">
<div id="tagcloud" style="text-align:justify">
<a href="#" target="LayouTest" rel="1" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" rel="2" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" rel="3" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" rel="4" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" rel="6" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" rel="5" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" rel="4" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" rel="3" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" rel="2" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" rel="1" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Cloud</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Topics</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Tag</a>
<a href="#" target="LayouTest" style="text-decoration: none;">Cloud</a>
</div>
<script type="text/javascript" charset="utf-8">
$.fn.tagcloud.defaults = {
@ -244,7 +244,7 @@ var solr= $.getJSON("/solr/collection1/select?q=*:*&defType=edismax&start=0&rows
<td>&nbsp;|&nbsp;<a href="yacysearch.html" target="LayouTest">Pictures</a></td>
<td>&nbsp;|&nbsp;<a href="CacheResource_p.html" target="LayouTest">Cache</a></td>
<td>&nbsp;|&nbsp;<a href="proxy.html" target="LayouTest">Augmented Browsing</a></td>
<td>&nbsp;|&nbsp;<a href="HostBrowser.html" target="LayouTest"><img src="env/grafics/minitree.png" width="15" height="8" /></a></td>
<td>&nbsp;|&nbsp;<a href="HostBrowser.html" target="LayouTest"><img src="env/grafics/minitree.png" width="15" height="8" title="Browse index" alt="Browse index"/></a></td>
<td>&nbsp;|&nbsp;<a href="yacysearch.html" target="LayouTest">Snapshots</a></td>
</tr>
<tr>

@ -142,6 +142,7 @@ public class ConfigSearchPage_p {
prop.putHTML(SwitchboardConstants.GREETING_HOMEPAGE, sb.getConfig(SwitchboardConstants.GREETING_HOMEPAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_LARGE_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_LARGE_IMAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_SMALL_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, ""));
prop.putHTML(SwitchboardConstants.GREETING_IMAGE_ALT, sb.getConfig(SwitchboardConstants.GREETING_IMAGE_ALT, ""));
prop.putHTML(SwitchboardConstants.INDEX_FORWARD, sb.getConfig(SwitchboardConstants.INDEX_FORWARD, ""));
prop.put("publicTopmenu", sb.getConfigBool("publicTopmenu", false) ? 1 : 0);
prop.put("search.options", sb.getConfigBool("search.options", false) ? 1 : 0);

@ -28,7 +28,7 @@
</fieldset>
</form>
<hr />
<p>Cookies at this browser:</p>
<h3>Cookies at this browser:</h3>
<p>
<script type="text/javascript">
<!--
@ -39,16 +39,16 @@
#(cookiesout)#
::
<hr />
<p>Cookies coming to server:</p>
<h3>Cookies coming to server:</h3>
#(/cookiesout)#
<p>#{cookiesout}#
#[string]#
#[string]#<br />
#{/cookiesout}#</p>
#(cookiesin)#
::
<hr />
<p>Cookies server sent:</p>
<h3>Cookies server sent:</h3>
#(/cookiesin)#
<p>#{cookiesin}#
#[name]# = #[value]#
@ -57,7 +57,6 @@
<p class="info">YaCy is a GPL'ed project
with the target of implementing a P2P-based global search engine.<br />
Architecture (C) by Michael Peter Christen,
<img src="env/grafics/mcemailh.gif" alt="Mail-Adresse von Michael Peter Christen" />
</p>
#%env/templates/footer.template%#
</body>

@ -29,6 +29,7 @@
import java.util.Iterator;
import java.util.Map;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.protocol.ResponseHeader;
import net.yacy.cora.util.CommonPattern;
@ -38,7 +39,7 @@ import net.yacy.server.servletProperties;
public class CookieTest_p {
public static serverObjects respond(final ResponseHeader header, final serverObjects post, final serverSwitch env) {
public static serverObjects respond(final RequestHeader header, final serverObjects post, final serverSwitch env) {
// case if no values are requested
@ -83,8 +84,14 @@ public class CookieTest_p {
//header.
}
prop.put("cookiesout", "1");
prop.putHTML("cookiesout_0_string", header.getHeaderCookies().replaceAll(";",";<br />"));
//prop.put("cookiesout", "1");
String[] cookielst = header.getHeaderCookies().split(";");
int i = 0;
for (String singleco : cookielst) {
prop.putHTML("cookiesout_" + i + "_string", singleco + ";"); // output with ";" for compatiblity with cookiesin
i++;
}
prop.put("cookiesout", i);
return prop;
}
}

@ -63,7 +63,6 @@
<input type="hidden" name="deleteold" id="deleteold" value="on" />
<input type="hidden" name="mustnotmatch" id="mustnotmatch" value="" />
<input type="hidden" name="crawlingDomFilterCheck" id="crawlingDomFilterCheck" value="off" />
<input type="hidden" name="crawlingDomFilterDepth" id="crawlingDomFilterDepth" value="#[crawlingDomFilterDepth]#" />
</dd>
<dt><label>Limitation</label></dt>
<dd><table border="0" cellpadding="0" cellspacing="0"><tr valign="top">

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html>
<html>
<head>
<title>YaCy '#[clientname]#': Crawler</title>
#%env/templates/metas.template%#
@ -28,13 +28,14 @@
<fieldset id="queues" style="width:210px;float:left;">
<legend>Queues</legend>
<table border="0" class="watchCrawler">
<tbody>
<thead>
<tr class="TableHeader">
<th width="120">Queue<br/>&nbsp;</th>
<th width="60">Size<br/>&nbsp;</th>
<th width="30"><span class="glyphicon glyphicon-wrench"></span>
</th>
<th width="30"><span class="glyphicon glyphicon-wrench"></span></th>
</tr>
</thead>
<tbody>
<tr class="TableCellLight">
<td align="left"><a href="IndexCreateQueues_p.html?stack=LOCAL">Local Crawler</a></td>
<td align="right"><span id="localcrawlerqueuesize">#[localCrawlSize]#</span></td>
@ -79,7 +80,7 @@
</tbody>
</table>
#(terminate-button)#::
<form action="/Crawler_p.html" method="get" role="form">
<form action="/Crawler_p.html" method="get">
<input type="hidden" name="queues_terminate_all" value="" />
<button type="submit" class="btn btn-danger" onclick="return confirm('Confirm Termination of All Crawls')"><span class="glyphicon glyphicon-remove-circle"></span> Terminate All</button>
</form>
@ -88,12 +89,14 @@
<fieldset id="indexsize" style="width:240px;float:left;">
<legend>Index Size</legend>
<table border="0" class="watchCrawler">
<tbody>
<thead>
<tr class="TableHeader">
<th width="130">Database<br/>&nbsp;</th>
<th width="50">Entries<br/>&nbsp;</th>
<th width="40">Seg-<br/>ments</th>
</tr>
</thead>
<tbody>
<tr class="TableCellLight">
<td align="left">Documents<br/><a href="#[urlpublictextSolrURL]#">solr search api</a></td>
<td align="right"><span id="urlpublictextSize">#[urlpublictextSize]#</span></td>
@ -121,11 +124,13 @@
<legend>Progress</legend>
<form action="Crawler_p.html" method="get" enctype="multipart/form-data" accept-charset="UTF-8">
<table border="0" class="watchCrawler">
<tbody>
<thead>
<tr class="TableHeader">
<th width="160">Indicator<br/>&nbsp;</th>
<th width="300" colspan="4">Level<br/>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr class="TableCellLight">
<td align="left">Speed / PPM<br/>(Pages Per Minute)</td>
<td align="left" colspan="4">
@ -219,33 +224,39 @@ window.setInterval("setTableSize()", 1000);
<!-- crawl profile list -->
#(crawlProfilesShow)#::
<fieldset>
<legend>Running Crawls (#[count]#)</legend>
<legend id="runningCrawlsLegend">Running Crawls (#[count]#)</legend>
<table width="96%">
<tr><td>
<table border="0" summary="A list of crawl profiles and their current settings.">
<table border="0" summary="A list of crawl profiles and their current settings." id="crawlProfiles">
<colgroup>
<col width="16" />
<col width="140"/>
<col width="16" />
<col width="140"/>
</colgroup>
<tr class="TableHeader">
<td><strong>Name</strong></td>
#(debug)#::<td><strong>Count</strong></td>#(/debug)#
<td><strong>Status</strong></td>
</tr>
<thead>
<tr class="TableHeader">
<th><strong>Name</strong></th>
#(debug)#::<th id="headerDebug"><strong>Count</strong></th>#(/debug)#
<th><strong>Status</strong></th>
</tr>
</thead>
<tbody>
#{list}#
<tr class="TableCell#(dark)#Light::Dark#(/dark)#">
<td>#[name]#</td>
#(debug)#::<td>#[count]#</td>#(/debug)#
<td>#(terminateButton)#::
<div style="text-decoration:blink;float:left;">Running</div>
<form style="float:left;" action="Crawler_p.html" method="get" enctype="multipart/form-data" accept-charset="UTF-8"><div>
<input type="hidden" name="handle" value="#[handle]#" />
<input type="submit" name="terminate" value="Terminate" class="btn btn-danger btn-xs"/>
</div></form>
#(/terminateButton)#
</td>
</tr>
#{/list}#
<tr class="TableCell#(dark)#Light::Dark#(/dark)#" id="#[handle]#">
<td>#[name]#</td>
#(debug)#::<td>#[count]#</td>#(/debug)#
<td id="#[handle]#_status_cell">#(terminateButton)#::
<div id="#[handle]#_status" style="text-decoration:blink;float:left;">Running</div>
<form id="#[handle]#_terminate" style="float:left;" action="Crawler_p.html" method="get" enctype="multipart/form-data" accept-charset="UTF-8">
<div>
<input type="hidden" name="handle" value="#[handle]#" />
<input type="submit" name="terminate" value="Terminate" class="btn btn-danger btn-xs"/>
</div>
</form>
#(/terminateButton)#
</td>
</tr>
#{/list}#
</tbody>
</table>
</td>
#(linkstructure)#

@ -231,6 +231,16 @@
<dt>Action</dt>
<dd>#(syn1Status)#<input type="submit" name="syn1Activate" class="btn btn-sm btn-primary" value="Activate" />::<input type="submit" name="syn1Deactivate" class="btn btn-sm btn-primary" value="Deactivate" />#(/syn1Status)#</dd>
</dl>
<h4>Russian Thesaurus</h4>
<p>The data was converted to the YaCy synonym file format and part of the YaCy distribution.</p>
<dl>
<dt><label>Status</label></dt>
<dd>#(syn2Status)#<div class="info">Deactivated</div>::<div class="commit">Activated</div>#(/syn2Status)#</dd>
<dt>Action</dt>
<dd>#(syn2Status)#<input type="submit" name="syn2Activate" class="btn btn-sm btn-primary" value="Activate" />::<input type="submit" name="syn2Deactivate" class="btn btn-sm btn-primary" value="Deactivate" />#(/syn2Status)#</dd>
</dl>
</fieldset>
</form>
#%env/templates/footer.template%#

@ -45,10 +45,12 @@ public class DictionaryLoader_p {
final serverObjects prop = new serverObjects(); // return variable that accumulates replacements
final File synonyms_path = new File(sb.dictionariesPath, LibraryProvider.path_to_synonym_dictionaries);
final File synonym_de_default = new File(new File(new File(sb.appPath, "addon"), "synonyms"), "openthesaurus_de_yacy");
final File synonym_de_default = new File(sb.appPath, "addon/synonyms/openthesaurus_de_yacy");
final File synonym_de_production = new File(synonyms_path, synonym_de_default.getName());
final File synonym_en_default = new File(new File(new File(sb.appPath, "addon"), "synonyms"), "mobythesaurus_en_yacy");
final File synonym_en_default = new File(sb.appPath, "addon/synonyms/mobythesaurus_en_yacy");
final File synonym_en_production = new File(synonyms_path, synonym_en_default.getName());
final File synonym_ru_default = new File(sb.appPath, "addon/synonyms/thesaurus_ru_yacy");
final File synonym_ru_production = new File(synonyms_path, synonym_ru_default.getName());
/*
* distinguish the following cases:
* - dictionary file was not loaded -> actions: load the file
@ -70,7 +72,7 @@ public class DictionaryLoader_p {
// check here only if there is no possibility synonym libraries have been activated/deactivated
prop.put("syn0Status", synonym_de_production.exists() ? 1 : 0);
prop.put("syn1Status", synonym_en_production.exists() ? 1 : 0);
prop.put("syn2Status", synonym_ru_production.exists() ? 1 : 0);
return prop;
}
@ -322,11 +324,25 @@ public class DictionaryLoader_p {
}
SynonymLibrary.init(synonyms_path);
}
if (post.containsKey("syn2Deactivate")) {
synonym_ru_production.delete();
SynonymLibrary.init(synonyms_path);
}
if (post.containsKey("syn2Activate")) {
try {
FileUtils.copy(new FileInputStream(synonym_ru_default), synonym_ru_production);
} catch (IOException e) {
ConcurrentLog.logException(e);
}
SynonymLibrary.init(synonyms_path);
}
if (post != null) {
// check here if there is a possibility synonym libraries have been activated/deactivated
prop.put("syn0Status", synonym_de_production.exists() ? 1 : 0);
prop.put("syn1Status", synonym_en_production.exists() ? 1 : 0);
prop.put("syn2Status", synonym_ru_production.exists() ? 1 : 0);
}
// check status again

@ -57,7 +57,7 @@ public class IndexShare_p {
if (post.containsKey("indexsharesetting")) {
sb.setConfig(SwitchboardConstants.INDEX_DIST_ALLOW, post.containsKey("distribute"));
sb.setConfig("allowReceiveIndex", post.containsKey("receive"));
sb.setConfig(SwitchboardConstants.INDEX_RECEIVE_ALLOW, post.containsKey("receive"));
sb.setConfig("defaultLinkReceiveFrequency", post.getInt("linkfreq", 30));
sb.setConfig("defaultWordReceiveFrequency", post.getInt("wordfreq", 10));
}

@ -337,7 +337,7 @@ public class Load_RSS_p {
prop.putHTML("showitems_language", channel == null ? "" : channel.getLanguage());
prop.putHTML("showitems_date", (pubDate == null) ? "" : DateFormat.getDateTimeInstance().format(pubDate));
prop.putHTML("showitems_ttl", channel == null ? "" : channel.getTTL());
prop.putHTML("showitems_docs", channel == null ? "" : channel.getDocs());
prop.put("showitems_docs", feed.size()); // number of documents
Map<String, DigestURL> urls = new HashMap<String, DigestURL>();
for (final Hit item: feed) {

@ -9,6 +9,39 @@
}
</style>
<script type="text/javascript" src="js/sorttable.js"></script>
</head>
<body id="Network">
#(menu)#
#%env/templates/embeddedheader.template%#
::
#%env/templates/simpleheader.template%#
::
#%env/templates/header.template%#
<div class="SubMenu">
<h3>YaCy Network</h3>
<ul class="SubMenu">
<li><a href="Network.html" class="MenuItemLink">Network Overview</a></li>
<li><a href="Network.html?page=1&maxCount=1000" class="MenuItemLink">Active&nbsp;Principal&nbsp;and&nbsp;Senior&nbsp;Peers</a></li>
<li><a href="Network.html?page=2&maxCount=1000" class="MenuItemLink">Passive&nbsp;Senior&nbsp;Peers</a></li>
<li><a href="Network.html?page=3&maxCount=1000" class="MenuItemLink">Junior&nbsp;(fragment)&nbsp;Peers</a></li>
<li><a href="Network.html?page=5" class="MenuItemLink">Network History</a></li>
</ul>
</div>
#(/menu)#
<div id="api"><a href="Network.xml" id="apilink"><img src="/env/grafics/api.png" width="60" height="40" alt="API"/></a>
<span>The information that is presented on this page can also be retrieved as XML.
Click the API icon to see the XML.
To see a list of all APIs, please visit the <a href="http://www.yacy-websuche.de/wiki/index.php/Dev:API" target="_blank">API wiki page</a>.</span>
</div>
<script type="text/javascript">
document.getElementById("apilink").setAttribute("href", "Network.xml?" + window.location.search.substring(1));
</script>
#(page)#
<h2>YaCy Search Network '#[networkName]#'</h2>
<script type="text/javascript">
<!--
imagestub = "NetworkPicture.png?width=1024&height=720&bgcolor=FFFFFF&ct=15000&coronaangle=";
@ -45,39 +78,6 @@
}
-->
</script>
<script type="text/javascript" src="js/sorttable.js"></script>
</head>
<body id="Network">
#(menu)#
#%env/templates/embeddedheader.template%#
::
#%env/templates/simpleheader.template%#
::
#%env/templates/header.template%#
<div class="SubMenu">
<h3>YaCy Network</h3>
<ul class="SubMenu">
<li><a href="Network.html" class="MenuItemLink">Network Overview</a></li>
<li><a href="Network.html?page=1&maxCount=1000" class="MenuItemLink">Active&nbsp;Principal&nbsp;and&nbsp;Senior&nbsp;Peers</a></li>
<li><a href="Network.html?page=2&maxCount=1000" class="MenuItemLink">Passive&nbsp;Senior&nbsp;Peers</a></li>
<li><a href="Network.html?page=3&maxCount=1000" class="MenuItemLink">Junior&nbsp;(fragment)&nbsp;Peers</a></li>
<li><a href="Network.html?page=5" class="MenuItemLink">Network History</a></li>
</ul>
</div>
#(/menu)#
<div id="api"><a href="Network.xml" id="apilink"><img src="/env/grafics/api.png" width="60" height="40" alt="API"/></a>
<span>The information that is presented on this page can also be retrieved as XML.
Click the API icon to see the XML.
To see a list of all APIs, please visit the <a href="http://www.yacy-websuche.de/wiki/index.php/Dev:API" target="_blank">API wiki page</a>.</span>
</div>
<script type="text/javascript">
document.getElementById("apilink").setAttribute("href", "Network.xml?" + window.location.search.substring(1));
</script>
#(page)#
<h2>YaCy Search Network '#[networkName]#'</h2>
::
<h2>Active Principal and Senior Peers in '#[networkName]#' Network</h2>
::
@ -390,7 +390,7 @@ document.getElementById("apilink").setAttribute("href", "Network.xml?" + window.
scale: number of hours per scale unit in the bottom line
-->
<h3><b>Count of Connected Senior Peers</b> in the last two days, scale = 1h</h3>
<img src="/NetworkHistory.png?columns=cC&scale=1&maxtime=48" />
<img src="/NetworkHistory.png?columns=cC&scale=1&maxtime=48&width=809" />
<h3><b>Count of all Active Peers Per Day</b> in the last week, scale = 1d</h3>
<img src="/NetworkHistory.png?columns=aD&scale=24&maxtime=168" />
<h3><b>Count of all Active Peers Per Week</b> in the last 30d, scale = 7d</h3>

@ -97,8 +97,18 @@ public class NetworkHistory {
if (v != null && v.longValue() > 0) minpeers = Math.min(minpeers, (int) v.longValue());
}
}
maxpeers = 10 * ((maxpeers / 9 * 10) / 10);
minpeers = 10 * ((minpeers * 9 / 10) / 10);
if (minpeers == Integer.MAX_VALUE) minpeers=0; // no values
if (minpeers < 0) {
ConcurrentLog.warn("NetworkHistory", "Negative value in plot. columns:"+columns);
minpeers=0;
}
if (maxpeers-minpeers > 2*minpeers) minpeers=0; // if we are close enough to zero, use zero as minimum
int order=(int)Math.log10(maxpeers-minpeers);
if (order<1) order=1;
int scale=(int)Math.pow(10, order);
minpeers=(minpeers/scale)*scale;
maxpeers=((maxpeers/scale)+1)*scale;
if ((maxpeers-minpeers)/scale < 3) scale=Math.max(5,scale/2);
final int leftborder = 30;
final int rightborder = 10;
final int width = post.getInt("width", 768 + leftborder + rightborder);
@ -107,7 +117,7 @@ public class NetworkHistory {
final int topborder = 20;
final int bottomborder = 20;
final int vspace = height - topborder - bottomborder;
final int leftscale = 10 * (maxpeers / 100);
final int leftscale = scale;
String timestr = maxtime + " HOURS";
if (maxtime > 24 && maxtime % 24 == 0) timestr = (maxtime / 24) + " DAYS";
if (maxtime == 168) timestr = "WEEK";
@ -120,12 +130,14 @@ public class NetworkHistory {
if (columns.contains("cC")) headline += ", ACTIVE SENIOR PEERS";
if (columns.contains("cD")) headline += ", PASSIVE SENIOR PEERS";
if (columns.contains("cP")) headline += ", POTENTIAL JUNIOR PEERS";
if (columns.contains("cI")) headline = "YACY PEER '" + sb.peers.myName() + "' INDEX SIZE HISTORY: NUMBER OF DOCUMENTS";
if (columns.contains("cR")) headline = "YACY PEER '" + sb.peers.myName() + "' INDEX SIZE HISTORY: NUMBER OF RWI ENTRIES";
if (columns.contains("cI")) headline = "YACY PEER '" + sb.peers.myName().toUpperCase() + "' INDEX SIZE HISTORY: NUMBER OF DOCUMENTS";
if (columns.contains("cR")) headline = "YACY PEER '" + sb.peers.myName().toUpperCase() + "' INDEX SIZE HISTORY: NUMBER OF RWI ENTRIES";
ChartPlotter chart = new ChartPlotter(width, height, 0xFFFFFFl, 0x000000l, 0xAAAAAAl, leftborder, rightborder, topborder, bottomborder, headline, "IN THE LAST " + timestr);
int pixelperscale = Math.max(16, hspace / (maxtime / bottomscale));
long pps = (long)hspace * (long)bottomscale / maxtime;
int pixelperscale = Math.max(8, (int)pps );
chart.declareDimension(ChartPlotter.DIMENSION_BOTTOM, bottomscale, pixelperscale, -maxtime, 0x000000l, 0xCCCCCCl, "TIME/HOURS");
pixelperscale = Math.max(16, 10 * ((vspace * leftscale / (maxpeers - minpeers)) / 10));
pps = (long)vspace * (long)leftscale / (maxpeers-minpeers);
pixelperscale = Math.max(8, (int)pps );
chart.declareDimension(ChartPlotter.DIMENSION_LEFT, leftscale, pixelperscale, minpeers, 0x008800l, null , columns.contains("cI") ? "DOCUMENTS" : columns.contains("cR") ? "RWIs" : "PEERS");
// write the data

@ -43,6 +43,10 @@
A change in the personal profile will create a news entry. You can see recently made changes of
profile entries on the Network page, where that profile change is visualized with a '*' beside the 'P' (profile) - selector.
</li>
<li>
Publishing of added or modified translation for the user interface. Other peers may include it in their local translation list.
To publish a translation, use the integrated <a href="Translator_p.html">translation editor</a> to add a translation and publish it afterwards.
</li>
</ul>
<p>
More news services will follow.

@ -63,7 +63,7 @@ public class PerformanceMemory_p {
System.gc();
prop.put("gc", "1");
prop.put("autoreload.checked", "1");
} else {
} else if (post.containsKey("dummy")) {
boolean simulatedshortmemory = post.containsKey("simulatedshortmemory");
MemoryControl.setSimulatedShortStatus(simulatedshortmemory);
if (simulatedshortmemory) prop.put("autoreload.checked", "1");

@ -62,56 +62,55 @@ public class QuickCrawlLink_p {
final serverObjects prop = new serverObjects();
final Switchboard sb = (Switchboard) env;
// get segment
Segment indexSegment = sb.index;
int port = sb.getConfigInt("port", 8090);
if (post == null) {
// send back usage example
prop.put("mode", "0");
// get the http host header
final String hostSocket = header.get(HeaderFramework.CONNECTION_PROP_HOST);
//String host = hostSocket;
int port = 80;
final int pos = hostSocket.indexOf(':',0);
// get the http host header
if (header.containsKey(HeaderFramework.HOST)) {
final String hostSocket = header.get(HeaderFramework.HOST);
final int pos = hostSocket.indexOf(':', 0);
if (pos != -1) {
port = NumberTools.parseIntDecSubstring(hostSocket, pos + 1);
//host = hostSocket.substring(0, pos);
}
}
prop.put("mode_host", Domains.LOCALHOST);
prop.put("mode_port", port);
prop.put("mode_host", Domains.LOCALHOST);
prop.put("mode_port", port);
if (post == null) {
// send back usage example
prop.put("mode", "0");
return prop;
}
prop.put("mode", "1");
// get the URL
String crawlingStart = post.get("url",null);
crawlingStart = UTF8.decodeURL(crawlingStart);
// get the browser title
final String title = post.get("title",null);
// get other parameters if set
final String crawlingMustMatch = post.get("mustmatch", CrawlProfile.MATCH_ALL_STRING);
final String crawlingMustNotMatch = post.get("mustnotmatch", CrawlProfile.MATCH_NEVER_STRING);
final int CrawlingDepth = post.getInt("crawlingDepth", 0);
final boolean crawlingQ = post.get("crawlingQ", "").equals("on");
final boolean followFrames = post.get("followFrames", "").equals("on");
final boolean obeyHtmlRobotsNoindex = post.get("obeyHtmlRobotsNoindex", "").equals("on");
final boolean obeyHtmlRobotsNofollow = post.get("obeyHtmlRobotsNofollow", "").equals("on");
final boolean indexText = post.get("indexText", "off").equals("on");
final boolean indexMedia = post.get("indexMedia", "off").equals("on");
final boolean storeHTCache = post.get("storeHTCache", "").equals("on");
final boolean remoteIndexing = post.get("crawlOrder", "").equals("on");
final String collection = post.get("collection", "user");
prop.put("mode_url", (crawlingStart == null) ? "unknown" : crawlingStart);
prop.putHTML("mode_title", (title == null) ? "unknown" : title);
if (crawlingStart != null) {
prop.put("mode", "1");
crawlingStart = UTF8.decodeURL(crawlingStart);
// get segment
Segment indexSegment = sb.index;
// get the browser title
final String title = post.get("title", null);
// get other parameters if set
final String crawlingMustMatch = post.get("mustmatch", CrawlProfile.MATCH_ALL_STRING);
final String crawlingMustNotMatch = post.get("mustnotmatch", CrawlProfile.MATCH_NEVER_STRING);
final int CrawlingDepth = post.getInt("crawlingDepth", 0);
final boolean crawlingQ = post.get("crawlingQ", "").equals("on");
final boolean followFrames = post.get("followFrames", "").equals("on");
final boolean obeyHtmlRobotsNoindex = post.get("obeyHtmlRobotsNoindex", "").equals("on");
final boolean obeyHtmlRobotsNofollow = post.get("obeyHtmlRobotsNofollow", "").equals("on");
final boolean indexText = post.get("indexText", "off").equals("on");
final boolean indexMedia = post.get("indexMedia", "off").equals("on");
final boolean storeHTCache = post.get("storeHTCache", "").equals("on");
final boolean remoteIndexing = post.get("crawlOrder", "").equals("on");
final String collection = post.get("collection", "user");
prop.put("mode_url", (crawlingStart == null) ? "unknown" : crawlingStart);
prop.putHTML("mode_title", (title == null) ? "unknown" : title);
crawlingStart = crawlingStart.trim();
try {crawlingStart = new DigestURL(crawlingStart).toNormalform(true);} catch (final MalformedURLException e1) {}

@ -38,6 +38,7 @@ import net.yacy.cora.order.NaturalOrder;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.sorting.ConcurrentScoreMap;
import net.yacy.cora.sorting.ScoreMap;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.kelondro.index.Row;
import net.yacy.kelondro.index.Row.Entry;
import net.yacy.peers.NewsDB;
@ -258,7 +259,7 @@ public class Supporter {
urlhash = null;
}
if (urlhash==null) {
System.out.println("Supporter: bad url '" + url + "' from news record " + record.toString());
ConcurrentLog.info("Supporter", "bad url '" + url + "' from news record " + record.toString());
continue;
}
if ((vote = negativeHashes.get(urlhash)) != null) {

@ -69,10 +69,6 @@
</script>
#(/surftips)#
#(display)#
#%env/templates/simplefooter.template%#
::
#%env/templates/footer.template%#
#(/display)#
</body>
</html>

@ -313,7 +313,7 @@ public class Table_API_p {
} else {
prop.put("showtable_list_" + count + "_isCrawlerStart", 0);
}
prop.putHTML("showtable_list_" + count + "_inline_url", "http://" + sb.myPublicIP() + ":" + sb.getPublicPort("port", 8090) + UTF8.String(row.get(WorkTables.TABLE_API_COL_URL)));
prop.putHTML("showtable_list_" + count + "_inline_url", UTF8.String(row.get(WorkTables.TABLE_API_COL_URL)));
prop.put("showtable_list_" + count + "_scheduler_inline", inline ? "true" : "false");
prop.put("showtable_list_" + count + "_scheduler_filter", typefilter.pattern());
prop.put("showtable_list_" + count + "_scheduler_query", query.pattern());

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>YaCy '#[clientname]#': Translation News</title>
#%env/templates/metas.template%#
</head>
<body>
#%env/templates/header.template%#
#%env/templates/submenuComputation.template%#
<h2 class="yacy">Translation News for Language #[currentlang]#</h2>
<form method="post" enctype="multipart/form-data">
<p>
You can share your local addition to translations and distribute it to other peers.
The remote peer can vote on your translation and add it to the own local translation.<br>
(#[transsize]# entries available)&nbsp;&nbsp;<input type="submit" class="btn btn-default" name="publishtranslation" value="Publish">
&nbsp;&nbsp;<small>You can check your outgoing messages <a href="News.html?page=3">here</a></small>
</p>
</form>
#(errmsg)#::<p class="error">Please activate a different language <a href='ConfigBasic.html'>here</a></p>#(/errmsg)#
#{results}#
<!-- link begin -->
<fieldset>
<table>
<tr>
<th>File:</th><th><a href="#[url]#" target="transnewsfile">#[filename]#</a></th><th>Originator</th>
</tr>
<tr>
<td>English:</td><td>#[source]#</td><td></td>
</tr>
#(existing)#::
<tr>
<td>existing</td><td class="warning">#[target]#</td><td></td>
</tr>
#(/existing)#
<tr>
<td>Translation:</td><td>#[target]#</td><td>#[peername]#</td>
</tr>
<tr><td><small>score #[score]#</small></td>
<td>&nbsp;
<a href="TransNews_p.html?voteNegative=#[refid]#" title="negative vote">
<span class="warning glyphicon glyphicon-thumbs-down"</span></a>
&nbsp;&nbsp;
<a href="TransNews_p.html?votePositive=#[refid]#&amp;filename=#[filename]#&amp;source=#[source]#&amp;target=#[target]#" title="positive vote" >
<span class="success glyphicon glyphicon-thumbs-up"></span></a>
&nbsp;&nbsp;<small>Vote on this translation. If you vote positive the translation is added to your local translation list.</small>
</td><td></td>
</tr>
</table>
</fieldset>
<!-- link end -->
#{/results}#
<p>
<br>
</p>
#%env/templates/footer.template%#
</body>
</html>

@ -0,0 +1,325 @@
// TransNews_p.java
//
// This is a part of YaCy, a peer-to-peer based web search engine
// published on http://yacy.net
//
// This file is contributed by Burkhard Buelte
//
// $LastChangedDate$
// $LastChangedRevision$
// $LastChangedBy$
//
// LICENSE
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.sorting.ConcurrentScoreMap;
import net.yacy.cora.sorting.ScoreMap;
import net.yacy.cora.util.SpaceExceededException;
import net.yacy.peers.NewsDB;
import net.yacy.peers.NewsPool;
import net.yacy.search.Switchboard;
import net.yacy.server.serverObjects;
import net.yacy.server.serverSwitch;
import net.yacy.utils.crypt;
import net.yacy.utils.translation.TranslationManager;
public class TransNews_p {
public static serverObjects respond(final RequestHeader header, final serverObjects post, final serverSwitch env) {
final Switchboard sb = (Switchboard) env;
final serverObjects prop = new serverObjects();
String currentlang = sb.getConfig("locale.language", "default");
prop.put("currentlang", currentlang);
if ("default".equals(currentlang) || "browser".equals(currentlang)) {
prop.put("errmsg", 1); // msg: activate diff lng
prop.put("transsize", 0);
return prop;
} else {
prop.put("errmsg", 0);
}
TranslationManager transMgr = new TranslationManager();
File locallangFile = transMgr.getScratchFile(new File(currentlang + ".lng"));
Map<String, Map<String, String>> localTrans = transMgr.loadTranslationsLists(locallangFile);
// calculate size of local translations list
int size = 0;
for (Map<String, String> lst : localTrans.values()) {
size += lst.size();
}
prop.put("transsize", size);
// read voting
if ((post != null) && post.containsKey("publishtranslation")) {
Iterator<String> filenameit = localTrans.keySet().iterator();
int msgcounter = 0;
while (filenameit.hasNext()) {
String file = filenameit.next();
Map<String, String> tmptrans = localTrans.get(file);
for (String sourcetxt : tmptrans.keySet()) {
String targettxt = tmptrans.get(sourcetxt);
if (targettxt != null && !targettxt.isEmpty()) {
boolean sendit = true;
// check if already published (in newsPool)
Iterator<NewsDB.Record> it = sb.peers.newsPool.recordIterator(NewsPool.INCOMING_DB);
while (it.hasNext()) {
NewsDB.Record rtmp = it.next();
if (rtmp == null) {
continue;
}
if (NewsPool.CATEGORY_TRANSLATION_ADD.equals(rtmp.category())) {
String tmplng = rtmp.attribute("language", null);
String tmpfile = rtmp.attribute("file", null);
String tmpsource = rtmp.attribute("source", null);
//String tmptarget = rtmp.attribute("target", null);
// if news with file and source exist (maybe from other peer) - skip sending another msg (to avoid confusion)
if ((tmplng != null && tmplng.equals(currentlang)) && (tmpfile != null && tmpfile.equals(file))
&& (tmpsource != null && tmpsource.equals(sourcetxt))) {
sendit = false;
break;
}
}
}
if (sendit) {
final HashMap<String, String> map = new HashMap<String, String>();
map.put("language", currentlang);
map.put("file", file);
map.put("source", sourcetxt);
map.put("target", targettxt);
map.put("#", Integer.toString(msgcounter++));
sb.peers.newsPool.publishMyNews(sb.peers.mySeed(), NewsPool.CATEGORY_TRANSLATION_ADD, map);
}
}
}
}
}
String refid;
if ((post != null) && ((refid = post.get("voteNegative", null)) != null)) {
// make new news message with voting
if (!sb.isRobinsonMode()) {
final HashMap<String, String> map = new HashMap<String, String>();
map.put("language", currentlang);
map.put("file", crypt.simpleDecode(post.get("filename", "")));
map.put("source", crypt.simpleDecode(post.get("source", "")));
map.put("target", crypt.simpleDecode(post.get("target", "")));
map.put("vote", "negative");
map.put("refid", refid);
sb.peers.newsPool.publishMyNews(sb.peers.mySeed(), NewsPool.CATEGORY_TRANSLATION_VOTE_ADD, map);
try {
sb.peers.newsPool.moveOff(NewsPool.INCOMING_DB, refid);
} catch (IOException | SpaceExceededException ex) {
}
}
}
if ((post != null) && ((refid = post.get("votePositive", null)) != null)) {
final String filename = post.get("filename");
File lngfile = new File(sb.getAppPath("locale.source", "locales"), currentlang + ".lng");
transMgr = new TranslationManager(lngfile); // load full language for check if entry is new (globally)
if (transMgr.addTranslation(filename, post.get("source"), post.get("target"))) {
// add to local translation extension
transMgr.addTranslation(localTrans, filename, post.get("source"), post.get("target"));
transMgr.saveAsLngFile(currentlang, locallangFile, localTrans); // save local-trans to local-file
transMgr.translateFile(filename); // ad-hoc translate file with new/added text
} // TODO: shall we post voting if translation is not new ?
// make new news message with voting
final HashMap<String, String> map = new HashMap<String, String>();
map.put("language", currentlang);
map.put("file", crypt.simpleDecode(filename));
map.put("source", crypt.simpleDecode(post.get("source", "")));
map.put("target", crypt.simpleDecode(post.get("target", "")));
map.put("vote", "positive");
map.put("refid", refid);
sb.peers.newsPool.publishMyNews(sb.peers.mySeed(), NewsPool.CATEGORY_TRANSLATION_VOTE_ADD, map);
try {
sb.peers.newsPool.moveOff(NewsPool.INCOMING_DB, refid);
} catch (IOException | SpaceExceededException ex) {
}
}
// create Translation voting list
final HashMap<String, Integer> negativeHashes = new HashMap<String, Integer>(); // a mapping from an url hash to Integer (count of votes)
final HashMap<String, Integer> positiveHashes = new HashMap<String, Integer>(); // a mapping from an url hash to Integer (count of votes)
accumulateVotes(sb, negativeHashes, positiveHashes, NewsPool.INCOMING_DB);
final ScoreMap<String> ranking = new ConcurrentScoreMap<String>(); // score cluster for url hashes
final HashMap<String, NewsDB.Record> translation = new HashMap<String, NewsDB.Record>(); // a mapping from an url hash to a kelondroRow.Entry with display properties
accumulateTranslations(sb, translation, ranking, negativeHashes, positiveHashes, NewsPool.INCOMING_DB);
// read out translation-news array and create property entries
final Iterator<String> k = ranking.keys(false);
int i = 0;
NewsDB.Record row;
String filename;
String source;
String target;
while (k.hasNext()) {
refid = k.next();
if (refid == null) {
continue;
}
row = translation.get(refid);
if (row == null) {
continue;
}
String lang = row.attribute("language", null);
filename = row.attribute("file", null);
source = row.attribute("source", null);
target = row.attribute("target", null);
if ((lang == null) || (filename == null) || (source == null) || (target == null)) {
continue;
}
if (!lang.equals(currentlang)) continue;
String existingtarget = null; //transMgr.getTranslation(filename, source);
Map<String, String> tmpMap = localTrans.get(filename);
if (tmpMap != null) {
existingtarget = tmpMap.get(source);
}
boolean altexist = existingtarget != null && !target.isEmpty() && !existingtarget.isEmpty() && !existingtarget.equals(target);
prop.put("results_" + i + "_refid", refid);
prop.put("results_" + i + "_url", filename); // url to local file
prop.put("results_" + i + "_targetlanguage", lang);
prop.put("results_" + i + "_filename", filename);
prop.putHTML("results_" + i + "_source", source);
prop.putHTML("results_" + i + "_target", target);
prop.put("results_" + i + "_existing", altexist);
prop.putHTML("results_" + i + "_existing_target", existingtarget);
prop.put("results_" + i + "_score", ranking.get(refid));
prop.put("results_" + i + "_peername", sb.peers.get(row.originator()).getName());
i++;
if (i >= 50) {
break;
}
}
prop.put("results", i);
return prop;
}
private static void accumulateVotes(final Switchboard sb, final HashMap<String, Integer> negativeHashes, final HashMap<String, Integer> positiveHashes, final int dbtype) {
final int maxCount = Math.min(1000, sb.peers.newsPool.size(dbtype));
NewsDB.Record newsrecord;
final Iterator<NewsDB.Record> recordIterator = sb.peers.newsPool.recordIterator(dbtype);
int j = 0;
while ((recordIterator.hasNext()) && (j++ < maxCount)) {
newsrecord = recordIterator.next();
if (newsrecord == null) {
continue;
}
if (newsrecord.category().equals(NewsPool.CATEGORY_TRANSLATION_VOTE_ADD)) {
final String refid = newsrecord.attribute("refid", "");
final String vote = newsrecord.attribute("vote", "");
final int factor = ((dbtype == NewsPool.OUTGOING_DB) || (dbtype == NewsPool.PUBLISHED_DB)) ? 2 : 1;
if (vote.equals("negative")) {
final Integer i = negativeHashes.get(refid);
if (i == null) {
negativeHashes.put(refid, Integer.valueOf(factor));
} else {
negativeHashes.put(refid, Integer.valueOf(i.intValue() + factor));
}
}
if (vote.equals("positive")) {
final Integer i = positiveHashes.get(refid);
if (i == null) {
positiveHashes.put(refid, Integer.valueOf(factor));
} else {
positiveHashes.put(refid, Integer.valueOf(i.intValue() + factor));
}
}
}
}
}
private static void accumulateTranslations(
final Switchboard sb,
final HashMap<String, NewsDB.Record> translationmsg, final ScoreMap<String> ranking,
final HashMap<String, Integer> negativeHashes, final HashMap<String, Integer> positiveHashes, final int dbtype) {
final int maxCount = Math.min(1000, sb.peers.newsPool.size(dbtype));
NewsDB.Record newsrecord;
final Iterator<NewsDB.Record> recordIterator = sb.peers.newsPool.recordIterator(dbtype);
int j = 0;
String refid = "";
String targetlanguage ="";
String filename="";
String source="";
String target="";
int score = 0;
Integer vote;
while ((recordIterator.hasNext()) && (j++ < maxCount)) {
newsrecord = recordIterator.next();
if (newsrecord == null) {
continue;
}
if ((newsrecord.category().equals(NewsPool.CATEGORY_TRANSLATION_ADD))
&& ((sb.peers.get(newsrecord.originator())) != null)) {
refid = newsrecord.id();
targetlanguage = newsrecord.attribute("language", "");
filename = newsrecord.attribute("file", "");
source = newsrecord.attribute("source", "");
target = newsrecord.attribute("target", "");
if (refid.isEmpty() || targetlanguage.isEmpty() || filename.isEmpty() || source.isEmpty() || target.isEmpty()) {
continue;
}
score = 0;
}
// add/subtract votes and write record
if ((vote = negativeHashes.get(refid)) != null) {
score -= vote.intValue();
}
if ((vote = positiveHashes.get(refid)) != null) {
score += vote.intValue();
}
// consider double-entries
if (translationmsg.containsKey(refid)) {
ranking.inc(refid, score);
} else {
ranking.set(refid, score);
translationmsg.put(refid, newsrecord);
}
}
}
}

@ -17,7 +17,7 @@
<legend>
<label>UI Translation</label>
</legend>
<p>Target Language: <b>#[targetlang]#</b></p><p class="error">#[errmsg]#</p>
<p>Target Language: <b>#[targetlang]#</b></p> #(errmsg)#::<p class="error">activate a different language <a href='ConfigBasic.html'>here</a></p>#(/errmsg)#
<label for="sourcefile">Source File</label>
<select name="sourcefile" onchange="submit();">
#{filelist}#
@ -36,7 +36,7 @@
<label for="targettxt#[tokenid]#" >#[sourcetxt]#</label>
</td>
<td style="border-bottom: solid gray; border-bottom-width: 1px;" valign="top" nowrap>
<input type="text" name="targettxt#[tokenid]#" id="targettxt#[tokenid]#" size="80" value="#[targettxt]#" #(filteruntranslated)#disabled::#(/filteruntranslated)#/>#(filteruntranslated)#<button name="editapproved" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-pencil"/></button>::<button name="approve" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-ok-sign" style="color: green"/></button>#(/filteruntranslated)#
<input type="text" name="targettxt#[tokenid]#" id="targettxt#[tokenid]#" size="80" value="#[targettxt]#" title="#[targettxt]#" #(filteruntranslated)#disabled::#(/filteruntranslated)#/>#(filteruntranslated)#<button name="editapproved" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-pencil"/></button>::<button name="approve" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-ok-sign" style="color: green"/></button>#(/filteruntranslated)#
</td>
</tr>
#{/textlist}#
@ -46,7 +46,7 @@
</fieldset>
</form>
<p>Check for remote translation proposals and/or share your own added translations <a href="TransNews_p.html">Translation News</a></p>
#%env/templates/footer.template%#
</body>
</html>

@ -29,7 +29,7 @@ import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverObjects;
import net.yacy.server.serverSwitch;
import net.yacy.server.servletProperties;
import net.yacy.utils.translation.CreateTranslationMasters;
import net.yacy.utils.translation.TranslationManager;
public class Translator_p {
@ -38,23 +38,23 @@ public class Translator_p {
final servletProperties prop = new servletProperties();
final Switchboard sb = (Switchboard) env;
String langcfg = env.getConfig("locale.language", "default");
String langcfg = sb.getConfig("locale.language", "default");
prop.put("targetlang", langcfg);
if ("default".equals(langcfg)) {
prop.put("errmsg", "activate a different language");
if ("default".equals(langcfg) || "browser".equals(langcfg)) {
prop.put("errmsg", 1); // msg: activate diff lng
return prop;
} else {
prop.put("errmsg", "");
prop.put("errmsg", 0);
}
File lngfile = new File("locales", langcfg + ".lng");
CreateTranslationMasters ctm = new CreateTranslationMasters(/*new File ("locales","master.lng.xlf")*/);
File lngfile = new File(sb.getAppPath("locale.source", "locales"), langcfg + ".lng");
TranslationManager localTransMgr = new TranslationManager(/*new File ("locales","master.lng.xlf")*/);
File masterxlf = new File("locales", "master.lng.xlf");
if (!masterxlf.exists()) ctm.createMasterTranslationLists(masterxlf);
Map<String, Map<String, String>> origTrans = ctm.joinMasterTranslationLists(masterxlf, lngfile);
final File locallngfile = ctm.getScratchFile(lngfile);
Map<String, Map<String, String>> localTrans = ctm.loadTranslationsLists(locallngfile); // TODO: this will read file twice
File masterxlf = new File(sb.getAppPath("locale.source", "locales"), "master.lng.xlf");
if (!masterxlf.exists()) localTransMgr.createMasterTranslationLists(masterxlf);
Map<String, Map<String, String>> origTrans = localTransMgr.joinMasterTranslationLists(masterxlf, lngfile);
final File locallngfile = localTransMgr.getScratchFile(lngfile);
Map<String, Map<String, String>> localTrans = localTransMgr.loadTranslationsLists(locallngfile); // TODO: this will read file twice
int i = 0;
if (origTrans.size() > 0) {
String filename = origTrans.keySet().iterator().next();
@ -114,7 +114,7 @@ public class Translator_p {
if (i == textlistid && post != null) {
if (editapproved) { // switch already translated in edit mode by copying to local translation
// not saved here as not yet modified/approved
ctm.addTranslation(localTrans, filename, sourcetext, targettxt);
localTransMgr.addTranslation(localTrans, filename, sourcetext, targettxt);
} else {
String t = post.get("targettxt" + Integer.toString(textlistid));
// correct common partial html markup (part of text identification for words also used as html parameter)
@ -125,7 +125,7 @@ public class Translator_p {
targettxt = t;
// add changes to original (for display) and local (for save)
origTextList.put(sourcetext, targettxt);
changed = ctm.addTranslation(localTrans, filename, sourcetext, targettxt);
changed = localTransMgr.addTranslation(localTrans, filename, sourcetext, targettxt);
}
}
prop.putHTML("textlist_" + i + "_sourcetxt", sourcetext);
@ -138,7 +138,7 @@ public class Translator_p {
changed = true;
}
if (changed) {
ctm.saveAsLngFile(langcfg, locallngfile, localTrans);
localTransMgr.saveAsLngFile(langcfg, locallngfile, localTrans);
// adhoc translate this file
// 1. get/calc the path
final String htRootPath = env.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT);
@ -147,7 +147,7 @@ public class Translator_p {
// get absolute file by adding relative filename from translationlist
final File sourceFile = new File(sourceDir, filename);
final File destFile = new File(destDir, filename);
ctm.translateFile(sourceFile, destFile, origTextList); // do the translation
localTransMgr.translateFile(sourceFile, destFile, origTextList); // do the translation
}
}
prop.put("textlist", i);

@ -39,7 +39,6 @@ import net.yacy.cora.order.Base64Order;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.sorting.ClusteredScoreMap;
import net.yacy.cora.util.CommonPattern;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.peers.graphics.WebStructureGraph;
import net.yacy.search.Switchboard;
import net.yacy.server.serverObjects;

@ -47,7 +47,7 @@ public class YaCySearchPluginFF {
final serverObjects prop = new serverObjects();
// getting the http host header
final String hostSocket = header.get(HeaderFramework.CONNECTION_PROP_HOST);
final String hostSocket = header.get(HeaderFramework.HOST);
String host = hostSocket;
int port = 80;

@ -0,0 +1,4 @@
#{lists}#
#{items}##[item]#
#{/items}#
#{/lists}#

@ -31,7 +31,7 @@
<tr><th>Item</th><th>URL</th><th>Success</th><th>Message</th></tr>
<tr>
<td>#[item]#</td>
<td><a href="#[url]#">#[url]#</a></td>
<td>#(success)#::<a href="#[url]#">#[url]#</a>#(/success)#</td>
<td>#(success)#fail::ok#(/success)#</td>
<td>#(success)##[message]#::<a href="#[message]#" target="_blank">#[message]#</a>#(/success)#</td>
</tr>

@ -22,7 +22,6 @@ import java.io.File;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import net.yacy.yacy;
@ -30,7 +29,6 @@ import net.yacy.cora.document.encoding.UTF8;
import net.yacy.cora.order.Base64Order;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.search.Switchboard;
import net.yacy.search.index.Fulltext;
import net.yacy.server.serverObjects;
import net.yacy.server.serverSwitch;
@ -63,12 +61,19 @@ public class share {
// push mode: this does a document upload
prop.put("mode", 1);
prop.put("success", 0);
prop.put("mode_success", 0);
if (post == null) return prop;
// check file name
String filename = post.get("data", "");
if (!filename.startsWith(Fulltext.yacy_dump_prefix) || !filename.endsWith(".xml.gz")) return prop;
if (filename.isEmpty()) {
prop.put("mode_success_message", "file name is empty");
return prop;
}
if (!filename.startsWith(Fulltext.yacy_dump_prefix) || !filename.endsWith(".xml.gz")) {
prop.put("mode_success_message", "no index dump file (" + Fulltext.yacy_dump_prefix + "*.xml.gz)");
return prop;
}
// check data
String dataString = post.get("data$file", "");
@ -99,7 +104,7 @@ public class share {
return prop;
}
prop.put("success", 1);
prop.put("mode_success", 1);
return prop;
}

@ -52,7 +52,7 @@ public class autoconfig {
final boolean yacyonly = env.getConfigBool(SwitchboardConstants.PROXY_YACY_ONLY, false);
// get the http host header
final String hostSocket = header.get(HeaderFramework.CONNECTION_PROP_HOST);
final String hostSocket = header.get(HeaderFramework.HOST);
String host = hostSocket;
int port = 80;

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>YaCy '#[clientname]#': Websearch Comparison</title>
<link rel="search" type="application/opensearchdescription+xml" title="Compare Yacy on '#[clientname]#'" href="opensearchdescription.xml?compare_yacy=true&amp;left=#[search_left]#&amp;right=#[search_right]#" />
<link rel="search" type="application/opensearchdescription+xml" title="Compare Yacy '#[clientname]#'" href="opensearchdescription.xml?compare_yacy=true&amp;left=#[search_left]#&amp;right=#[search_right]#" />
#%env/templates/metas.template%#
</head>
<body>

@ -43,19 +43,19 @@ public class compare_yacy {
searchengines.put("YaCy (local)", "yacysearch.html?display=2&resource=local&query=");
//searchengines.put("google.com", "https://www.google.com/#q=");
searchengines.put("startpage.com", "https://startpage.com/do/search?cat=web&query=");
searchengines.put("bing.com", "http://www.bing.com/search?q=");
searchengines.put("metager.de", "http://www.metager.de/meta/cgi-bin/meta.ger1?eingabe=");
searchengines.put("metager2.de (web)", "http://www.metager2.de/search.php?ses=web&q=");
searchengines.put("metager2.de (international)", "http://www.metager2.de/search.php?ses=international&q=");
searchengines.put("yahoo.com", "http://search.yahoo.com/search?p=");
//searchengines.put("romso.de", "http://romso.de/?q="); // no serach service 2016-01-02
searchengines.put("Wikipedia English", "http://en.wikipedia.org/wiki/");
searchengines.put("Wikipedia Deutsch", "http://de.wikipedia.org/wiki/");
searchengines.put("Sciencenet", "http://sciencenet.fzk.de:8080/yacysearch.html?verify=true&resource=global&nav=all&display=2&meanCount=5&query=");
searchengines.put("bing.com", "https://www.bing.com/search?q=");
searchengines.put("metager.de", "https://www.metager.de/meta/cgi-bin/meta.ger1?eingabe=");
searchengines.put("metager2.de (web)", "https://www.metager2.de/search.php?ses=web&q=");
searchengines.put("metager2.de (international)", "https://www.metager2.de/search.php?ses=international&q=");
//searchengines.put("yahoo.com", "https://search.yahoo.com/search?p="); // no search service in iframe 2016-08-17 : "Load denied by X-Frame-Options: does not permit cross-origin framing."
//searchengines.put("romso.de", "http://romso.de/?q="); // no search service 2016-01-02
searchengines.put("Wikipedia English", "https://en.wikipedia.org/wiki/");
searchengines.put("Wikipedia Deutsch", "https://de.wikipedia.org/wiki/");
//searchengines.put("Sciencenet", "http://sciencenet.fzk.de:8080/yacysearch.html?verify=true&resource=global&nav=all&display=2&meanCount=5&query="); // no search service 2016-08-17
//searchengines.put("dbpedia", "http://dbpedia.neofonie.de/browse/~:"); // no search service 2016-01-02
searchengines.put("wolfram alpha", "http://www.wolframalpha.com/input/?i=");
searchengines.put("OAIster@OCLC", "http://oaister.worldcat.org/search?q=");
searchengines.put("oai.yacy.net", "http://oai.yacy.net/yacysearch.html?verify=true&resource=local&nav=all&display=2&meanCount=5&query=");
searchengines.put("wolfram alpha", "https://www.wolframalpha.com/input/?i=");
searchengines.put("OAIster@OCLC", "https://oaister.worldcat.org/search?q=");
//searchengines.put("oai.yacy.net", "http://oai.yacy.net/yacysearch.html?verify=true&resource=local&nav=all&display=2&meanCount=5&query="); // no search service 2016-08-17
}
public static serverObjects respond(final RequestHeader header, final serverObjects post, final serverSwitch env) {

File diff suppressed because one or more lines are too long

@ -1,3 +1,2 @@
</div>
</div>
</div>

@ -3,7 +3,7 @@
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" id="navbar-brand" href="#[promoteSearchPageGreeting.homepage]#" style="position:absolute;top:-6px;display:inline;white-space:nowrap;">
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle">&nbsp;<span id="greeting"></span>
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" alt="#[promoteSearchPageGreeting.imageAlt]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle">&nbsp;<span id="greeting"></span>
</a>
</div>
</div>

@ -9,7 +9,7 @@
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" id="navbar-brand" href="/" style="position:absolute;top:-6px;display:inline;white-space:nowrap;">
<img id="greeting-icon" class="yacylogo" src="/env/grafics/yacy.png" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle;float:left;">
<img id="greeting-icon" class="yacylogo" src="/env/grafics/yacy.png" alt="YaCy" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle;float:left;">
<span style="position:absolute;top:50%;float:left;">&nbsp;Administration</span>
</a>
<form class="navbar-form" method="get" accept-charset="UTF-8" action="/yacysearch.html" style="padding-left:200px;max-width:400px;">
@ -23,34 +23,34 @@
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li id="header_restart">
<form action="/Steering.html" method="get" role="form">
<form action="/Steering.html" method="get">
<input type="hidden" name="restart" value="" />
<button accesskey="s" type="submit" class="btn btn-inverse navbar-btn label-warning" onclick="return confirm('Confirm Re-Start')"><span class="glyphicon glyphicon-fire"></span> Re-Start</button>
</form>
</li>
<li>&nbsp;</li>
<li id="header_shutdown">
<form action="/Steering.html" method="get" role="form">
<form action="/Steering.html" method="get">
<input type="hidden" name="shutdown" value="" />
<button accesskey="s" type="submit" class="btn btn-inverse navbar-btn label-danger" onclick="return confirm('Confirm Shutdown')"><span class="glyphicon glyphicon-off"></span> Shutdown</button>
</form>
</li>
<li id="header_help" class="dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle"><span class="glyphicon glyphicon-question-sign"></span></a>
<a href="#" data-toggle="dropdown" class="dropdown-toggle" aria-label="Help" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-question-sign"></span></a>
<ul class="dropdown-menu">
<li id="header_profile"><a href="ViewProfile.html?hash=localhash">About This Page</a></li>
<li id="header_tutorial"><a href="http://yacy.net/tutorials/">YaCy Tutorials</a></li>
<li id="header_jslicense"><a href="jslicense.html" data-jslicense="1">JavaScript information</a></li>
<li class="divider"></li>
<li id="header_tutorial"><a href="http://yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Download YaCy</a></li>
<li id="header_tutorial"><a href="http://forum.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Community (Web Forums)</a></li>
<li id="header_tutorial"><a href="http://wiki.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Project Wiki</a></li>
<li id="header_tutorial"><a href="https://github.com/yacy/yacy_search_server/commits/master" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Git Repository</a></li>
<li id="header_tutorial"><a href="http://bugs.yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Bugtracker</a></li>
<li class="divider" role="separator"></li>
<li id="header_download"><a href="http://yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Download YaCy</a></li>
<li id="header_community"><a href="http://forum.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Community (Web Forums)</a></li>
<li id="header_wiki"><a href="http://wiki.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Project Wiki</a></li>
<li id="header_git"><a href="https://github.com/yacy/yacy_search_server/commits/master" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Git Repository</a></li>
<li id="header_bugs"><a href="http://bugs.yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Bugtracker</a></li>
</ul>
</li>
<li id="header_administration">
<form action="/index.html" method="get" role="form">
<form action="/index.html" method="get">
<button accesskey="s" type="submit" class="btn btn-inverse navbar-btn label-primary"><span class="glyphicon glyphicon-search"></span> Search Interface &raquo;</button>
</form>
</li>

@ -42,7 +42,6 @@ for the JavaScript code in this page.
<script src="/env/bootstrap/js/jquery.min.js"></script>
<script src="/env/bootstrap/js/bootstrap.min.js"></script>
<script src="/env/bootstrap/js/docs.min.js"></script>
<script src="/env/bootstrap/js/bootstrap-switch.min.js"></script>
<!-- Custom styles for this template, i.e. navigation (move this to base.css) -->

@ -1,3 +1,2 @@
</div>
</div>
</div>

@ -9,25 +9,25 @@
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" id="navbar-brand" href="#[promoteSearchPageGreeting.homepage]#" style="position:absolute;top:-6px;display:inline;white-space:nowrap;">
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle;float:left;">&nbsp;<span id="greeting" style="position:absolute; top:50%;float:left;"></span>
<img id="greeting-icon" class="yacylogo" src="#[promoteSearchPageGreeting.smallImage]#" alt="#[promoteSearchPageGreeting.imageAlt]#" style="height:auto; width:auto; max-width:200px; max-height:32px;vertical-align:middle;float:left;">&nbsp;<span id="greeting" style="position:absolute; top:50%;float:left;"></span>
</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li id="header_search" class="dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle">Search Interfaces<b class="caret"></b></a>
<ul class="dropdown-menu">
<a href="#" data-toggle="dropdown" class="dropdown-toggle" role="button" aria-haspopup="true" aria-expanded="false">Search Interfaces<b class="caret"></b></a>
<ul class="dropdown-menu" role="menu">
<li id="header_websearch"><a href="index.html" onclick="this.href='/index.html?handover='+document.searchform.search.value">Web Search</a></li>
<li id="header_filesearch"><a href="yacyinteractive.html" onclick="this.href='/yacyinteractive.html?handover='+document.searchform.search.value">File Search</a></li>
<li id="header_comparesearch"><a href="/compare_yacy.html?display=0">Compare Search</a></li>
<li id="header_hostbrowser"><a href="HostBrowser.html?hosts=">Index Browser</a></li>
<li id="header_urlviewer"><a href="ViewFile.html">URL Viewer</a></li>
<!--<li><a href="yacysearch_location.html">Location Search</a></li>-->
<li class="divider"></li>
<li class="divider" role="separator"></li>
<li>&nbsp;&nbsp;<i>Example Calls to the Search API:</i></li>
<li><a href="/yacysearch.json?query=www" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;YaCy JSON</a></li>
<li><a href="/yacysearch.rss?query=www" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;YaCy RSS/Opensearch</a></li>
<li><a href="/solr/select?hl=false&wt=opensearch&facet=true&facet.mincount=1&facet.field=url_file_ext_s&start=0&rows=10&sort=load_date_dt+desc&q=description_txt:[* TO *]" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;Solr RSS/Opensearch</a></li>
<li><a href="/solr/select?hl=false&wt=opensearch&facet=true&facet.mincount=1&facet.field=url_file_ext_s&start=0&rows=10&sort=load_date_dt+desc&q=description_txt:%5B*%20TO%20*%5D" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;Solr RSS/Opensearch</a></li>
<li><a href="/solr/select?hl=false&wt=yjson&facet=true&facet.mincount=1&facet.field=url_file_ext_s&start=0&rows=10&query=www" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;Solr Default Core / JSON</a></li>
<li><a href="/solr/collection1/select?q=*:*&defType=edismax&start=0&rows=3" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;Solr Default Core / XML</a></li>
<li><a href="/solr/webgraph/select?q=*:*&defType=edismax&start=0&rows=3" target="_blank"><i>API</i>&nbsp;&nbsp;&nbsp;Solr Webgraph Core / XML</a></li>
@ -35,21 +35,21 @@
</ul>
</li>
<li id="header_help" class="dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle"><span class="glyphicon glyphicon-question-sign"></span></a>
<ul class="dropdown-menu">
<a href="#" data-toggle="dropdown" class="dropdown-toggle" aria-label="Help" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-question-sign"></span></a>
<ul class="dropdown-menu" role="menu">
<li id="header_profile"><a href="ViewProfile.html?hash=localhash">About This Page</a></li>
<li id="header_tutorial"><a href="http://yacy.net/tutorials/">YaCy Tutorials</a></li>
<li id="header_jslicense"><a href="jslicense.html" data-jslicense="1">JavaScript information</a></li>
<li class="divider"></li>
<li id="header_tutorial"><a href="http://yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Download YaCy</a></li>
<li id="header_tutorial"><a href="http://forum.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Community (Web Forums)</a></li>
<li id="header_tutorial"><a href="http://wiki.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Project Wiki</a></li>
<li id="header_tutorial"><a href="https://github.com/yacy/yacy_search_server/commits/master" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Git Repository</a></li>
<li id="header_tutorial"><a href="http://bugs.yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Bugtracker</a></li>
<li class="divider" role="separator"></li>
<li id="header_download"><a href="http://yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Download YaCy</a></li>
<li id="header_community"><a href="http://forum.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Community (Web Forums)</a></li>
<li id="header_wiki"><a href="http://wiki.yacy.de" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Project Wiki</a></li>
<li id="header_git"><a href="https://github.com/yacy/yacy_search_server/commits/master" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Git Repository</a></li>
<li id="header_bugs"><a href="http://bugs.yacy.net" target="_blank"><i>external</i>&nbsp;&nbsp;&nbsp;Bugtracker</a></li>
</ul>
</li>
<li id="header_administration">
<form action="/Status.html" method="get" role="form">
<form action="/Status.html" method="get">
<button accesskey="s" type="submit" class="btn btn-default navbar-btn"><span class="glyphicon glyphicon-cog"></span> Administration &raquo;</button>
</form>
</li>

@ -33,6 +33,7 @@
<ul class="SubMenu">
<li><a href="Surftips.html" class="MenuItemLink">Surftips</a></li>
<li><a href="Wiki.html?display=1" class="MenuItemLink">Local Peer Wiki</a></li>
<li><a href="TransNews_p.html" class="MenuItemLink #(authorized)#lock::unlock#(/authorized)#">UI Translations</a></li>
</ul>
</div>
</div>

@ -1,11 +1,11 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html>
<html>
<head>
#(forward)#::<meta http-equiv="REFRESH" content="0; url=#[target]#" />#(/forward)#
<title>YaCy '#[clientname]#': Search Page</title>
#%env/templates/metas.template%#
<link rel="alternate" type="application/rss+xml" title="Search for #[former]#" href="yacysearch.rss?query=#[former]#" />
<link rel="search" type="application/opensearchdescription+xml" title="YaCy Search on '#[clientname]#'" href="opensearchdescription.xml" />
<link rel="search" type="application/opensearchdescription+xml" title="YaCy '#[clientname]#'" href="opensearchdescription.xml" />
<script type="text/javascript" src="/env/bootstrap/js/typeahead.jquery.min.js"></script>
<script type="text/javascript" src="js/html.js"></script>
<script type="text/javascript">
@ -50,7 +50,7 @@
<!-- this is the single exception in page design where we do not want a top-left application icon because we show a big one in the middle of the page -->
<script>document.getElementById("greeting-icon").src="/env/grafics/invisible.png"</script>
<h2 class="yacy"><a href="#[promoteSearchPageGreeting.homepage]#" class="yacylogo"><img src="#[promoteSearchPageGreeting.largeImage]#" alt="yacy" style="margin: auto;"/></a></h2>
<h2 class="yacy"><a href="#[promoteSearchPageGreeting.homepage]#" class="yacylogo"><img src="#[promoteSearchPageGreeting.largeImage]#" alt="#[promoteSearchPageGreeting.imageAlt]#" style="margin: auto;"/></a></h2>
<h2 class="yacy">#[promoteSearchPageGreeting]#</h2>
<form class="search form-inline" action="yacysearch.html" method="get" id="searchform" accept-charset="UTF-8">
@ -85,29 +85,35 @@
::
</fieldset>
<table>
<table role="presentation">
<tr>
<td><label for="count">Results per page</label>:</td>
<td><label id="maxResultsLabel">Results per page</label>:</td>
<td>
<input type="radio" name="maximumRecords" id="mr10" value="10" #(count-10)#::checked="checked"#(/count-10)#/><label for="mr10">10</label>
<input type="radio" name="maximumRecords" id="mr50" value="50" #(count-50)#::checked="checked"#(/count-50)#/><label for="mr50">50</label>
<input type="radio" name="maximumRecords" id="mr100" value="100" #(count-100)#::checked="checked"#(/count-100)#/><label for="mr100">100</label>
<fieldset aria-labelledby="maxResultsLabel">
<input type="radio" name="maximumRecords" id="mr10" value="10" #(count-10)#::checked="checked"#(/count-10)#/><label for="mr10">10</label>
<input type="radio" name="maximumRecords" id="mr50" value="50" #(count-50)#::checked="checked"#(/count-50)#/><label for="mr50">50</label>
<input type="radio" name="maximumRecords" id="mr100" value="100" #(count-100)#::checked="checked"#(/count-100)#/><label for="mr100">100</label>
</fieldset>
</td>
</tr>
#(resource-select)#::
<tr>
#(resource-select)#::
<td><label for="resource">Resource</label>:</td>
<td><label id="resourceLabel">Resource</label>:</td>
<td>
<input type="radio" name="resource" id="rglobal" value="global" checked="checked" /><label for="rglobal">the peer-to-peer network</label>
<input type="radio" name="resource" id="rlocal" value="local"><label for="rlocal">only the local index</label>
<fieldset aria-labelledby="resourceLabel">
<input type="radio" name="resource" id="rglobal" value="global" checked="checked" /><label for="rglobal">the peer-to-peer network</label>
<input type="radio" name="resource" id="rlocal" value="local"><label for="rlocal">only the local index</label>
</fieldset>
</td>::
<td><label for="resource">Resource</label>:</td>
<td><label id="resourceLabel">Resource</label>:</td>
<td>
<input type="radio" name="resource" id="rglobal" value="global"/><label for="rglobal">the peer-to-peer network</label>
<input type="radio" name="resource" id="rlocal" value="local" checked="checked"/><label for="rlocal">only the local index</label>
<fieldset aria-labelledby="resourceLabel">
<input type="radio" name="resource" id="rglobal" value="global"/><label for="rglobal">the peer-to-peer network</label>
<input type="radio" name="resource" id="rlocal" value="local" checked="checked"/><label for="rlocal">only the local index</label>
</fieldset>
</td>
#(/resource-select)#
</tr>
#(/resource-select)#
<tr>
<td>
<label for="prefermaskfilter">Prefer mask</label>:
@ -149,6 +155,12 @@
<dd>only pages with as-author-anotated &lt;author&gt;</dd>
<dt>tld:&lt;tld&gt;</dt>
<dd>only pages from top-level-domains &lt;tld&gt;</dd>
#(datesincontent)#::
<dt>on:&lt;date&gt;</dt>
<dd>only pages with &lt;date&gt; in content</dd>
<dt>from:&lt;date1&gt; to:&lt;date2&gt;</dt>
<dd>only pages with a date between &lt;date1&gt; and &lt;date2&gt; in content</dd>
#(/datesincontent)#
<dt>/http</dt>
<dd>only resources from http or https servers</dd>
<dt>/ftp</dt>

@ -33,6 +33,7 @@ import net.yacy.cora.document.analysis.Classification.ContentDomain;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.search.schema.CollectionSchema;
import net.yacy.server.serverObjects;
import net.yacy.server.serverSwitch;
@ -65,9 +66,11 @@ public class index {
int searchoptions = (post == null) ? 0 : Math.min(1, post.getInt("searchoptions", 0));
if (!sb.getConfigBool("search.options", true)) {
searchoptions = 0;
} else { // show heuristic hint on search option screen
// (only if heuristic is ON by config)
} else {
// show heuristic hint on search option screen (only if heuristic is ON by config)
prop.put("searchoptions_heuristic", sb.getConfigBool(SwitchboardConstants.HEURISTIC_OPENSEARCH, false));
// show date search options (only if dates_in_content_dts search target field is active)
prop.put("searchoptions_datesincontent", sb.index.fulltext().getDefaultConfiguration().contains(CollectionSchema.dates_in_content_dts));
}
final String former = (post == null) ? "" : post.get("former", "");
final int count = Math.min(100, (post == null) ? 10 : post.getInt("count", 10));
@ -96,7 +99,9 @@ public class index {
prop.put(SwitchboardConstants.GREETING_HOMEPAGE, sb.getConfig(SwitchboardConstants.GREETING_HOMEPAGE, ""));
prop.put("topmenu_" + SwitchboardConstants.GREETING_HOMEPAGE, sb.getConfig(SwitchboardConstants.GREETING_HOMEPAGE, ""));
prop.put("topmenu_" + SwitchboardConstants.GREETING_SMALL_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, ""));
prop.put("topmenu_" + SwitchboardConstants.GREETING_IMAGE_ALT, sb.getConfig(SwitchboardConstants.GREETING_IMAGE_ALT, ""));
prop.put(SwitchboardConstants.GREETING_LARGE_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_LARGE_IMAGE, ""));
prop.put(SwitchboardConstants.GREETING_IMAGE_ALT, sb.getConfig(SwitchboardConstants.GREETING_IMAGE_ALT, ""));
prop.putHTML("former", former);
prop.put("num-results", "0");
prop.put("excluded", "0");

@ -28,13 +28,35 @@ var refreshInterval=2;
var wait=0;
var changing=false; //change the interval
var statusLoaded=true;
/* Running crawls table DOM element */
var crawlsTable;
/* Size of the running crawls table header */
var crawlsHeadLength;
/* Running crawls legend DOM element */
var runningCrawlsLegend;
/* true when debug is enabled */
var debug;
function initCrawler(){
initCrawlProfiles();
refresh();
//loadInterval=window.setInterval("refresh()", refreshInterval*1000);
countInterval=window.setInterval("countdown()", 1000);
}
/**
* Init variables used to refresh the running crawls table
*/
function initCrawlProfiles() {
debug = document.getElementById("headerDebug") != null;
crawlsTable = document.getElementById("crawlProfiles");
if(crawlsTable != null && crawlsTable.rows != null) {
crawlsHeadLength = crawlsTable.tHead != null ? crawlsTable.tHead.rows.length : 0;
}
runningCrawlsLegend = document.getElementById("runningCrawlsLegend");
}
function changeInterval(){
if(!changing){
window.clearInterval(countInterval);
@ -84,9 +106,9 @@ function handleStatus(){
return;
}
var statusResponse = statusRPC.responseXML;
statusTag=getFirstChild(statusResponse, "status");
var statusTag = getFirstChild(statusResponse, "status");
ppm=getValue(getFirstChild(statusTag, "ppm"));
var ppm = getValue(getFirstChild(statusTag, "ppm"));
var ppmNum = document.getElementById("ppmNum");
removeAllChildren(ppmNum);
@ -102,21 +124,21 @@ function handleStatus(){
// ppmBar end
// traffic output (no bar up to now)
traffic = getFirstChild(statusTag, "traffic");
trafficCrawlerValue = getValue(getFirstChild(traffic, "crawler"));
trafCrawlerSpan = document.getElementById("trafficCrawler");
var traffic = getFirstChild(statusTag, "traffic");
var trafficCrawlerValue = getValue(getFirstChild(traffic, "crawler"));
var trafCrawlerSpan = document.getElementById("trafficCrawler");
removeAllChildren(trafCrawlerSpan);
trafCrawlerSpan.appendChild(document.createTextNode(Math.round((trafficCrawlerValue) / 1024 / 10.24) / 100));
dbsize=getFirstChild(statusTag, "dbsize");
urlpublictext=getValue(getFirstChild(dbsize, "urlpublictext"));
urlpublictextSegmentCount=getValue(getFirstChild(dbsize, "urlpublictextSegmentCount"));
webgraph=getValue(getFirstChild(dbsize, "webgraph"));
webgraphSegmentCount=getValue(getFirstChild(dbsize, "webgraphSegmentCount"));
citation=getValue(getFirstChild(dbsize, "citation"));
citationSegmentCount=getValue(getFirstChild(dbsize, "citationSegmentCount"));
rwipublictext=getValue(getFirstChild(dbsize, "rwipublictext"));
rwipublictextSegmentCount=getValue(getFirstChild(dbsize, "rwipublictextSegmentCount"));
var dbsize = getFirstChild(statusTag, "dbsize");
var urlpublictext = getValue(getFirstChild(dbsize, "urlpublictext"));
var urlpublictextSegmentCount = getValue(getFirstChild(dbsize, "urlpublictextSegmentCount"));
var webgraph = getValue(getFirstChild(dbsize, "webgraph"));
var webgraphSegmentCount = getValue(getFirstChild(dbsize, "webgraphSegmentCount"));
var citation = getValue(getFirstChild(dbsize, "citation"));
var citationSegmentCount = getValue(getFirstChild(dbsize, "citationSegmentCount"));
var rwipublictext = getValue(getFirstChild(dbsize, "rwipublictext"));
var rwipublictextSegmentCount = getValue(getFirstChild(dbsize, "rwipublictextSegmentCount"));
document.getElementById("urlpublictextSize").firstChild.nodeValue=urlpublictext;
document.getElementById("urlpublictextSegmentCount").firstChild.nodeValue=urlpublictextSegmentCount;
document.getElementById("webgraphSize").firstChild.nodeValue=webgraph;
@ -125,55 +147,223 @@ function handleStatus(){
document.getElementById("citationSegmentCount").firstChild.nodeValue=citationSegmentCount;
document.getElementById("rwipublictextSize").firstChild.nodeValue=rwipublictext;
document.getElementById("rwipublictextSegmentCount").firstChild.nodeValue=rwipublictextSegmentCount;
refreshRunningCrawls(statusTag);
postprocessing=getFirstChild(statusTag, "postprocessing");
var postprocessing = getFirstChild(statusTag, "postprocessing");
document.getElementById("postprocessing_status").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "status"));
document.getElementById("postprocessing_collection").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "collectionRemainingCount"));
document.getElementById("postprocessing_webgraph").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "webgraphRemainingCount"));
document.getElementById("postprocessing_remainingTimeMinutes").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "remainingTimeMinutes"));
document.getElementById("postprocessing_remainingTimeSeconds").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "remainingTimeSeconds"));
postprocessingElapsedTime=parseInt(getValue(getFirstChild(postprocessing, "ElapsedTime")));
postprocessingRemainingTime=parseInt(getValue(getFirstChild(postprocessing, "RemainingTime")));
p = 100 * postprocessingElapsedTime / (postprocessingElapsedTime + postprocessingRemainingTime) || 0;
var postprocessingElapsedTime = parseInt(getValue(getFirstChild(postprocessing, "ElapsedTime")));
var postprocessingRemainingTime = parseInt(getValue(getFirstChild(postprocessing, "RemainingTime")));
var p = 100 * postprocessingElapsedTime / (postprocessingElapsedTime + postprocessingRemainingTime) || 0;
document.getElementById("postprocessing_bar").firstChild.setAttribute("value", p);
//document.getElementById("postprocessing_speed").firstChild.nodeValue=getValue(getFirstChild(postprocessing, "speed"));
load=getFirstChild(statusTag, "load");
var load = getFirstChild(statusTag, "load");
document.getElementById("load").firstChild.nodeValue=getValue(load);
loaderqueue=getFirstChild(statusTag, "loaderqueue");
loaderqueue_size=getValue(getFirstChild(loaderqueue, "size"));
loaderqueue_max=getValue(getFirstChild(loaderqueue, "max"));
var loaderqueue = getFirstChild(statusTag, "loaderqueue");
var loaderqueue_size = getValue(getFirstChild(loaderqueue, "size"));
var loaderqueue_max = getValue(getFirstChild(loaderqueue, "max"));
document.getElementById("loaderqueuesize").firstChild.nodeValue=loaderqueue_size;
document.getElementById("loaderqueuemax").firstChild.nodeValue=loaderqueue_max;
localcrawlerqueue=getFirstChild(statusTag, "localcrawlerqueue");
localcrawlerqueue_size=getValue(getFirstChild(localcrawlerqueue, "size"));
localcrawlerqueue_state=getValue(getFirstChild(localcrawlerqueue, "state"));
var localcrawlerqueue = getFirstChild(statusTag, "localcrawlerqueue");
var localcrawlerqueue_size = getValue(getFirstChild(localcrawlerqueue, "size"));
var localcrawlerqueue_state = getValue(getFirstChild(localcrawlerqueue, "state"));
document.getElementById("localcrawlerqueuesize").firstChild.nodeValue=localcrawlerqueue_size;
putQueueState("localcrawler", localcrawlerqueue_state);
limitcrawlerqueue=getFirstChild(statusTag, "limitcrawlerqueue");
limitcrawlerqueue_size=getValue(getFirstChild(limitcrawlerqueue, "size"));
limitcrawlerqueue_state=getValue(getFirstChild(limitcrawlerqueue, "state"));
var limitcrawlerqueue = getFirstChild(statusTag, "limitcrawlerqueue");
var limitcrawlerqueue_size = getValue(getFirstChild(limitcrawlerqueue, "size"));
var limitcrawlerqueue_state = getValue(getFirstChild(limitcrawlerqueue, "state"));
document.getElementById("limitcrawlerqueuesize").firstChild.nodeValue=limitcrawlerqueue_size;
putQueueState("limitcrawler", limitcrawlerqueue_state);
remotecrawlerqueue=getFirstChild(statusTag, "remotecrawlerqueue");
remotecrawlerqueue_size=getValue(getFirstChild(remotecrawlerqueue, "size"));
remotecrawlerqueue_state=getValue(getFirstChild(remotecrawlerqueue, "state"));
var remotecrawlerqueue = getFirstChild(statusTag, "remotecrawlerqueue");
var remotecrawlerqueue_size = getValue(getFirstChild(remotecrawlerqueue, "size"));
var remotecrawlerqueue_state = getValue(getFirstChild(remotecrawlerqueue, "state"));
document.getElementById("remotecrawlerqueuesize").firstChild.nodeValue=remotecrawlerqueue_size;
putQueueState("remotecrawler", remotecrawlerqueue_state);
noloadcrawlerqueue=getFirstChild(statusTag, "noloadcrawlerqueue");
noloadcrawlerqueue_size=getValue(getFirstChild(noloadcrawlerqueue, "size"));
noloadcrawlerqueue_state=getValue(getFirstChild(noloadcrawlerqueue, "state"));
var noloadcrawlerqueue = getFirstChild(statusTag, "noloadcrawlerqueue");
var noloadcrawlerqueue_size = getValue(getFirstChild(noloadcrawlerqueue, "size"));
var noloadcrawlerqueue_state = getValue(getFirstChild(noloadcrawlerqueue, "state"));
document.getElementById("noloadcrawlerqueuesize").firstChild.nodeValue=noloadcrawlerqueue_size;
putQueueState("noloadcrawler", noloadcrawlerqueue_state);
statusLoaded=true;
}
/**
* Insert a new crawl line to the end of the running crawls table
* @param table crawls table HTML DOM node
* @param crawl crawl profile node from status_p.xml
* @param handle {String} identifier of the running crawl profile
* @param status {String} running status of the crawl profile
*/
function insertCrawlRaw(table, crawl, handle, status) {
/* Insert a row in the table at the end */
var newRow = table.insertRow();
newRow.className = ((table.rows.length - crawlsHeadLength) % 2) == 0 ? "TableCellLight" : "TableCellDark";
newRow.id = handle;
/* Insert name cell */
var newCell = newRow.insertCell();
var newText = document.createTextNode(getValue(getFirstChild(crawl, "name")));
newCell.appendChild(newText);
if(debug) {
/* Insert count cell when debug is enabled */
newCell = newRow.insertCell();
newCell.textContent = getValue(getFirstChild(crawl, "count"));
}
/* Insert status cell */
newCell = newRow.insertCell();
newCell.id = handle + "_status_cell";
if(status == "alive") {
var newDiv = document.createElement("div");
newDiv.id = handle + "_status";
newDiv.style = "text-decoration:blink;float:left;";
newText = document.createTextNode("Running");
newDiv.appendChild(newText);
newCell.appendChild(newDiv);
var newForm = document.createElement("form");
newForm.id = handle + "_terminate";
newForm.style = "float:left;";
newForm.action = "Crawler_p.html";
newForm.method = "get";
newForm.enctype="multipart/form-data";
newForm["accept-charset"]="UTF-8";
newDiv = document.createElement("div");
var newInput = document.createElement("input");
newInput.type = "hidden";
newInput.name = "handle";
newInput.value = handle;
newDiv.appendChild(newInput);
newInput = document.createElement("input");
newInput.type = "submit";
newInput.name = "terminate";
newInput.value = "Terminate";
newInput.className = "btn btn-danger btn-xs";
newDiv.appendChild(newInput);
newForm.appendChild(newDiv);
newCell.appendChild(newForm);
}
}
/**
* Refresh status cell text and terminate button presence
* @param handle name of the crawl
* @param status current crawl status label
*/
function refreshStatusCell(handle, status) {
var handleStatus = document.getElementById(handle + "_status");
if(handleStatus != null) {
handleStatus.textContent = status;
}
var terminateForm = document.getElementById(handle + "_terminate");
if(terminateForm != null && terminateForm.parentElement) {
terminateForm.parentElement.removeChild(terminateForm);
}
}
/**
* Refresh the count in running crawls legend
* @param legend the HTML DOM legend element
* @param crawls crawls node from xml api status_p.xml
*/
function refreshCrawlsLegend(legend, crawls) {
var count = crawls.getAttribute("count");
if(count && legend != null) {
legend.textContent = "Running Crawls (" + count + ")";
}
}
/**
* Refresh dark/light rows style
* @param table running crawls table
*/
function refreshRowsStyle(table, headLength) {
for(var i = headLength; i < table.rows.length; i++) {
raw = table.rows[i];
raw.className = ((i - headLength) % 2) == 0 ? "TableCellLight" : "TableCellDark";
}
}
/**
* Refresh running crawls table
*
* @param statusTag
* status tag from xml api status_p.xml
*/
function refreshRunningCrawls(statusTag) {
var crawls = getFirstChild(statusTag, "crawls");
/* crawls node should be present even when no crawl is running */
if(crawls != null) {
/* Update the table when present */
if(crawlsTable != null && crawlsTable.rows != null) {
var processedHandles = {}, crawlNode = getFirstChild(crawls, "crawl");
if(crawlNode) {
var handle, rowIndex, handleCell;
/* Loop on crawl node elements from xml */
for(; crawlNode; crawlNode = getNextSibling(crawlNode, "crawl")) {
handle = getValue(getFirstChild(crawlNode, "handle"));
if(handle != null) {
processedHandles[handle] = crawlNode;
status = getValue(getFirstChild(crawlNode, "status"));
/* Let's try to get the crawls table cell with id prefixed by this handle */
handleCell = document.getElementById(handle + "_status_cell");
if(handleCell == null) {
insertCrawlRaw(crawlsTable, crawlNode, handle, status);
refreshCrawlsLegend(runningCrawlsLegend, crawls);
refreshRowsStyle(crawlsTable, crawlsHeadLength);
} else if(status != "alive"){
refreshStatusCell(handle, status);
}
}
}
}
/* Collect raws to delete */
var raw, rawsToDelete = [];
for(var i = crawlsHeadLength; i < crawlsTable.rows.length; i++) {
raw = crawlsTable.rows[i];
if(processedHandles[raw.id] == null) {
rawsToDelete.push(raw);
}
}
/* Delete raws */
for(var i = 0; i < rawsToDelete.length; i++) {
raw = rawsToDelete[i];
raw.parentElement.removeChild(raw);
}
/* Refresh legend and rows style (dark/light alternate) */
if(rawsToDelete.length > 0) {
refreshCrawlsLegend(runningCrawlsLegend, crawls);
refreshRowsStyle(crawlsTable, crawlsHeadLength);
}
}
}
}
function putQueueState(queue, state) {
a = document.getElementById(queue + "stateA");
img = document.getElementById(queue + "stateIMG");

@ -3,6 +3,7 @@
version 2
7th April 2007
Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
fixed for YaCy 20th September 2016
Instructions:
Download this file
@ -17,7 +18,7 @@
@licstart The following is the entire license notice for the
JavaScript code in this file.
Copyright (c) 1997-2007 Stuart Langridge
Copyright (c) 1997-2007, 2016 Stuart Langridge, luccioman
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@ -172,7 +173,7 @@ sorttable = {
col = this.sorttable_columnindex;
rows = this.sorttable_tbody.rows;
for (var j=0; j<rows.length; j++) {
row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
row_array[row_array.length] = [sorttable.getCellText(rows[j], col), rows[j]];
}
/* If you want a stable sort, uncomment the following line */
//sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
@ -190,11 +191,38 @@ sorttable = {
}
},
/**
* Get text from cell at specified header column index. This handles correctly colspan values over 1 in data cells,
* but colspan values over 1 in header cells are not supported.
* @param tableRow {HTMLTableRowElement} a table row
* @param column {number} the column index : value between 0 and header row cells number
* @return {String} the cell text from the tableRow and column specified
*/
getCellText: function(tableRow, column) {
var cellsNb = tableRow.cells.length;
var cellText = '';
/* Current data cell index */
var cellIndex = 0;
/* Current header cell index */
var columnIndex = 0;
var colspan;
for(var cellIndex = 0; cellIndex < cellsNb && columnIndex < column; cellIndex++) {
colspan = tableRow.cells[cellIndex].colspan > 0 ? tableRow.cells[cellIndex].colspan : 1;
columnIndex += colspan;
}
/* This final test ensure we do not use an index out of bounds */
if(cellIndex < cellsNb) {
cellText = sorttable.getInnerText(tableRow.cells[cellIndex]);
}
return cellText;
},
guessType: function(table, column) {
// guess the type of a column based on its first non-blank row
sortfn = sorttable.sort_alpha;
for (var i=0; i<table.tBodies[0].rows.length; i++) {
text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
var tableRow = table.tBodies[0].rows[i];
text = sorttable.getCellText(tableRow, column);
if (text != '') {
if (text.match(/^-?[<5B>$<24>]?[\d,.]+%?$/)) {
return sorttable.sort_numeric;

@ -28,11 +28,6 @@
<td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></td>
<td><a href="/env/bootstrap/js/bootstrap-switch.js">bootstrap-switch.js</a> (3.0.0)</td>
</tr>
<tr>
<td><a href="/env/bootstrap/js/docs.min.js">docs.min.js</a></td>
<td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
<td><a href="https://raw.githubusercontent.com/imsky/holder/v2.3.1/holder.js">holder.js</a> (2.3.1)</td>
</tr>
<tr>
<td><a href="/env/bootstrap/js/html5shiv.js">html5shiv.js</a></td>
<td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>

@ -25,6 +25,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
@ -39,9 +40,19 @@ public class opensearchdescription {
String promoteSearchPageGreeting = env.getConfig(SwitchboardConstants.GREETING, "");
if (env.getConfigBool(SwitchboardConstants.GREETING_NETWORK_NAME, false)) promoteSearchPageGreeting = env.getConfig("network.unit.description", "");
String thisaddress = header.get("Host", Domains.LOCALHOST);
if (thisaddress.indexOf(':',0) == -1) thisaddress += ":" + env.getLocalPort();
String thisprotocol = env.getConfigBool("server.https", false) ? "https" : "http";
String thisaddress = header.get(HeaderFramework.HOST); // returns host:port (if not default http/https ports)
String thisprotocol = "http";
if (thisaddress == null) {
thisaddress = Domains.LOCALHOST + ":" + sb.getConfig("port", "8090");
} else {
final String sslport = ":" + sb.getConfig("port.ssl", "8443");
if (thisaddress.endsWith(sslport)) { // connection on ssl port, use https protocol
thisprotocol = "https";
}
}
/* YaCyDefaultServelt should have filled this custom header, making sure we know here wether original request is http or https
* (when default ports (80 and 443) are used, there is no way to distinguish the two schemes relying only on the Host header) */
thisprotocol = header.get(HeaderFramework.X_YACY_REQUEST_SCHEME, thisprotocol);
final serverObjects prop = new serverObjects();
prop.put("compareyacy", post != null && post.getBoolean("compare_yacy") ? 1 : 0);

@ -2,7 +2,7 @@
<OpenSearchDescription
xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:suggestions="http://www.opensearch.org/specifications/opensearch/extensions/suggestions/1.1">
<ShortName>#(compareyacy)#::Compare #(/compareyacy)#YaCy/#[clientname]#</ShortName>
<ShortName>#(compareyacy)#::Compare #(/compareyacy)#YaCy '#[clientname]#'</ShortName>
<LongName>YaCy.net - #[SearchPageGreeting]#</LongName>
<Image type="image/gif">#[thisprotocol]#://#[thisaddress]#/env/grafics/yacy.png</Image>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////Chiu+fBm+fRq+fRq+fRq+fRq+fRq8ehXMmk////////////////////////////++exjUqGfZsnjYsXbYsXbYsXbZsnjTp2W+fBr///////////////////////////+9exfs2r/69/L58+z58+z58+z59e/z59bChSn///////////////////////////+9fBnnz638+fX69O369e748un38Ob59O3Ll0fVrGz////////////////////////Jk0HJlUjXuYrWt4jVtYPr28T58+r59OzPn1fPnlX////////////////////////Rolu8eRXCiTPEjTvCijbNnlj169359e7Zs3vLlkf////////////////////////UqmrAgSLt3MP27eH1693169327+T59Ozo0rG/gB////////////////////////////+/gCDv4Mn48+v38Of59Oz58+v48+vr2b2+fRv///////////////////////////+9ehXr17n58+z48ejo0bDp07T48+zx49DBhCj///////////////////////////+/fhzjyJ/59Oz59OzQoVvNmU759Oz58+vKlUbXrnH////////////////////////LlkfUqmn59Oz48+vZtHzNm1D48+v59OzPoFjOnlX////////////////////////OnVPOnFL59e348+vq1rnEiC7u38j69vDXsHTIkT3////////////////////////UqWjIkD327+T58+3s2bzAgSLp07T79/Pmzqq+fBn///////////////////////////+/fx7v4Mr7+PTx5NDHkD3kyqP8+vjs2r+9exf///////////////////////////++fBjQoFnVq2zTp2bGjTjJk0LWrW7SpWC+exf////////////////////////////Nm1C6dQy7eBG8eBK9exe8ehS7dxC6dQzLlkj////////////AH///wB8x+sAf///AD/+PwA///8AP///AD///4A9PU+APoz/gB///4AdxvOAHoz/gB3368AfjU/AHT1PwB/+P
@ -17,7 +17,7 @@
<Url type="application/rss+xml" method="GET" template="#[thisprotocol]#://#[thisaddress]#/yacysearch.rss?nav=&amp;query={searchTerms}&amp;startRecord={startIndex?}&amp;maximumRecords={count?}&amp;nav=all&amp;resource=global" />
<Url type="application/atom+xml" method="GET" template="#[thisprotocol]#://#[thisaddress]#/yacysearch.atom?query={searchTerms}&amp;startRecord={startIndex?}&amp;maximumRecords={count?}&amp;resource=global" />
::
<Url type="text/html" method="GET" template="http://#[thisaddress]#/compare_yacy.html?query={searchTerms}&amp;left=#[search_left]#&amp;right=#[search_right]#&amp;display=2" />
<Url type="text/html" method="GET" template="#[thisprotocol]#://#[thisaddress]#/compare_yacy.html?query={searchTerms}&amp;left=#[search_left]#&amp;right=#[search_right]#&amp;display=2" />
#(/compareyacy)#
<Url type="application/x-suggestions+json" template="#[thisprotocol]#://#[thisaddress]#/suggest.json?query={searchTerms}"/>
<Url type="application/x-suggestions+xml" template="#[thisprotocol]#://#[thisaddress]#/suggest.xml?query={searchTerms}"/>

@ -11,7 +11,6 @@
<script src="/env/bootstrap/js/jquery.min.js"></script>
<script src="/env/bootstrap/js/bootstrap.min.js"></script>
<script src="/env/bootstrap/js/docs.min.js"></script>
<!-- Bootstrap core CSS -->
<link href="env/bootstrap/css/bootstrap.min.css" rel="stylesheet">
@ -59,7 +58,7 @@
</ul>
</li>
<li id="header_administration">
<form action="/Status.html" method="get" role="form">
<form action="/Status.html" method="get">
<button accesskey="s" type="submit" class="btn btn-inverse navbar-btn">Administration &raquo;</button>
</form>
</li>

@ -57,12 +57,13 @@ public final class hello {
final serverObjects prop = new serverObjects();
final long start = System.currentTimeMillis();
prop.put("message", "none");
final String clientip = header.get(HeaderFramework.CONNECTION_PROP_CLIENTIP, "<unknown>"); // read an artificial header addendum
String clientip = header.get(HeaderFramework.CONNECTION_PROP_CLIENTIP); // read an artificial header addendum
//ConcurrentLog.info("**hello-DEBUG**", "client request from = " + clientip);
final InetAddress ias = Domains.dnsResolve(clientip);
long time = System.currentTimeMillis();
final long time_dnsResolve = System.currentTimeMillis() - time;
if (ias == null) {
if (clientip == null) clientip = "<unknown>";
Network.log.info("hello/server: failed contacting seed; clientip not resolvable (clientip=" + clientip + ", time_dnsResolve=" + time_dnsResolve + ")");
prop.put("message", "cannot resolve your IP from your reported location " + clientip);
return prop;

@ -51,6 +51,7 @@ public final class list {
// return variable that accumulates replacements
final serverObjects prop = new serverObjects();
prop.put("list", ""); // init a empty return (error case)
if ((post == null) || (env == null)) return prop;
if (!Protocol.authentifyRequest(post, env)) return prop;
@ -66,7 +67,7 @@ public final class list {
if ((sb.isRobinsonMode()) && (!sb.isInMyCluster(otherPeerName))) {
// if we are a robinson cluster, answer only if this client is known by our network definition
return null;
return prop;
}
if (col.equals("black")) {
@ -85,8 +86,6 @@ public final class list {
}
prop.put("list",out.toString());
} else {
prop.put("list","");
}
return prop;

@ -71,8 +71,8 @@ public final class message {
if (!Protocol.authentifyRequest(post, env)) return prop;
final String process = post.get("process", "permission");
final String clientip = header.get(HeaderFramework.CONNECTION_PROP_CLIENTIP, "<unknown>"); // read an artificial header addendum
final InetAddress ias = Domains.dnsResolve(clientip);
final String clientip = header.get(HeaderFramework.CONNECTION_PROP_CLIENTIP); // read an artificial header addendum
final InetAddress ias = clientip != null ? Domains.dnsResolve(clientip) : null;
final int messagesize = 10240;
final int attachmentsize = 0;
@ -116,7 +116,7 @@ public final class message {
//Date remoteTime = yacyCore.parseUniversalDate((String) post.get(yacySeed.MYTIME)); // read remote time
Seed otherSeed;
try {
otherSeed = Seed.genRemoteSeed(otherSeedString, false, ias.getHostAddress());
otherSeed = Seed.genRemoteSeed(otherSeedString, false, ias == null ? null : ias.getHostAddress());
} catch (final IOException e) {
prop.put("response", "-1"); // don't accept messages for bad seeds
return prop;

@ -45,7 +45,6 @@ import net.yacy.cora.lod.vocabulary.Tagging;
import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.sorting.ConcurrentScoreMap;
import net.yacy.cora.sorting.ScoreMap;
import net.yacy.cora.sorting.WeakPriorityBlockingQueue;
import net.yacy.cora.storage.HandleSet;
@ -380,7 +379,9 @@ public final class search {
// prepare reference hints
final long timer = System.currentTimeMillis();
final ScoreMap<String> topicNavigator = sb.index.connectedRWI() ? theSearch.getTopics(5, 100) : new ConcurrentScoreMap<String>();
//final ScoreMap<String> topicNavigator = sb.index.connectedRWI() ? theSearch.getTopics(5, 100) : new ConcurrentScoreMap<String>();
final ScoreMap<String> topicNavigator = theSearch.getTopics(); // as there is currently no index interaction in getTopics(), we can use it by default
final StringBuilder refstr = new StringBuilder(6000);
final Iterator<String> navigatorIterator = topicNavigator.keys(false);
int i = 0;

@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.JSONObject;
import net.yacy.peers.Seed;
import net.yacy.search.Switchboard;
import net.yacy.server.serverCore;
@ -91,14 +92,14 @@ public final class seedlist {
Set<String> ips = seed.getIPs();
if (ips == null || ips.size() == 0) continue;
prop.putJSON("peers_" + count + "_map_0_k", Seed.HASH);
prop.put("peers_" + count + "_map_0_v", '"' + serverObjects.toJSON(seed.hash) + '"');
prop.put("peers_" + count + "_map_0_v", JSONObject.quote(seed.hash));
prop.put("peers_" + count + "_map_0_c", 1);
Map<String, String> map = seed.getMap();
int c = 1;
if (!addressonly) {
for (Map.Entry<String, String> m: map.entrySet()) {
prop.putJSON("peers_" + count + "_map_" + c + "_k", m.getKey());
prop.put("peers_" + count + "_map_" + c + "_v", '"' + serverObjects.toJSON(m.getValue()) + '"');
prop.put("peers_" + count + "_map_" + c + "_v", JSONObject.quote(m.getValue()));
prop.put("peers_" + count + "_map_" + c + "_c", 1);
c++;
}
@ -106,7 +107,7 @@ public final class seedlist {
// construct a list of ips
StringBuilder a = new StringBuilder();
a.append('[');
for (String ip: ips) a.append('"').append(serverObjects.toJSON(seed.getPublicAddress(ip))).append('"').append(',');
for (String ip: ips) a.append(JSONObject.quote(seed.getPublicAddress(ip))).append(',');
a.setCharAt(a.length()-1, ']');
prop.putJSON("peers_" + count + "_map_" + c + "_k", "Address");
prop.put("peers_" + count + "_map_" + c + "_v", a.toString());

@ -116,7 +116,7 @@ public final class transferRWI {
final int wordc = post.getInt("wordc", 0); // number of different words
final int entryc = post.getInt("entryc", 0); // number of entries in indexes
byte[] indexes = post.get("indexes", "").getBytes(); // the indexes, as list of word entries
boolean granted = sb.getConfigBool("allowReceiveIndex", false);
boolean granted = sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false);
final boolean blockBlacklist = sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_BLOCK_BLACKLIST, false);
final long cachelimit = sb.getConfigLong(SwitchboardConstants.WORDCACHE_MAX_COUNT, 100000);
final Seed otherPeer = sb.peers.get(iam);

@ -68,7 +68,7 @@ public final class transferURL {
final String youare = post.get("youare", ""); // seed hash of the target peer, needed for network stability
// final String key = post.get("key", ""); // transmission key
final int urlc = post.getInt("urlc", 0); // number of transported urls
final boolean granted = sb.getConfigBool("allowReceiveIndex", false);
final boolean granted = sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false);
final boolean blockBlacklist = sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_BLOCK_BLACKLIST, false);
// response values

@ -1,10 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html>
<html>
<head>
<title>#[former]# - YaCy '#[clientname]#': Search Page</title>
#%env/templates/metas.template%#
<link rel="alternate" type="application/rss+xml" title="Search for #[former]#" href="yacysearch.rss?query=#[former]#" />
<link rel="search" type="application/opensearchdescription+xml" title="YaCy Search on '#[clientname]#'" href="http://#[thisaddress]#/opensearchdescription.xml" />
<link rel="alternate" type="application/rss+xml" title="Search for #[former]#" href="yacysearch.rss?query=#[formerEncoded]#" />
<link rel="search" type="application/opensearchdescription+xml" title="YaCy '#[clientname]#'" href="http://#[thisaddress]#/opensearchdescription.xml" />
<link rel="stylesheet" type="text/css" media="screen" href="env/highslide.css" />
<script type="text/javascript" src="js/ajax.js"></script>
<script type="text/javascript" src="js/xml.js"></script>
@ -89,7 +89,7 @@ Use the RSS search result format to add static searches to your RSS reader, if y
<div class="row">
<div class="col-sm-8 col-sm-offset-4 col-md-9 col-md-offset-3 main">
<form class="search small" name="searchform" action="" method="get" accept-charset="UTF-8" style="position:fixed;top:8px;z-index:1052;max-width:500px;">
<form class="search small" name="searchform" method="get" accept-charset="UTF-8" style="position:fixed;top:8px;z-index:1052;max-width:500px;">
<div class="input-group">
<input name="query" id="search" type="text" class="form-control searchinput typeahead" size="40" maxlength="200" placeholder="#[promoteSearchPageGreeting]#" value="#[former]#" #(focus)#::autofocus="autofocus"#(/focus)# onFocus="this.select()" onclick="document.getElementById('Enter').innerHTML = 'search'"/>

@ -28,6 +28,9 @@
// if the shell's current path is HTROOT
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
@ -852,7 +855,14 @@ public class yacysearch {
}
prop.put("focus", focus ? 1 : 0); // focus search field
prop.put("searchagain", global ? "1" : "0");
prop.putHTML("former", originalquerystring.replaceAll(Segment.catchallString, "*"));
String former = originalquerystring.replaceAll(Segment.catchallString, "*");
prop.putHTML("former", former);
try {
prop.put("formerEncoded", URLEncoder.encode(former, StandardCharsets.UTF_8.name()));
} catch (UnsupportedEncodingException e) {
ConcurrentLog.warn("LOCAL_SEARCH", "Unsupported UTF-8 encoding!");
prop.put("formerEncoded", former);
}
prop.put("count", itemsPerPage);
prop.put("offset", startRecord);
prop.put("resource", global ? "global" : "local");
@ -877,4 +887,8 @@ public class yacysearch {
// return rewrite properties
return prop;
}
public static void main(String args[]) throws UnsupportedEncodingException {
System.out.println(URLEncoder.encode("aao?+ bbibu", StandardCharsets.UTF_8.name()));
}
}

@ -30,10 +30,10 @@
#(showMetadata)#::&nbsp;|&nbsp;<a href="solr/select?q=id:%22#[urlhash]#%22&defType=edismax&start=0&rows=1&core=collection1&wt=html" target="_blank" onclick="return hs.htmlExpand(this, { objectType: 'ajax'} )">Metadata</a>#(/showMetadata)#
#(showParser)#::&nbsp;|&nbsp;<a href="ViewFile.html?urlHash=#[urlhash]#&amp;words=#[words]#" target="_blank">Parser</a>#(/showParser)#
#(showCitation)#::&nbsp;|&nbsp;<a href="api/citation.html?hash=#[urlhash]#&filter=true" target="_blank">Citations</a>#(/showCitation)#
#(showPictures)#::&nbsp;|&nbsp;<a href="yacysearch.html?contentdom=image&amp;url=#[link]#&amp;query=#[former]# inurl:#[link]#" target="_blank">Pictures</a>#(/showPictures)#
#(showPictures)#::&nbsp;|&nbsp;<a href="yacysearch.html?contentdom=image&url=#[link]#&query=#[former]#+inurl:#[link]#" target="_blank">Pictures</a>#(/showPictures)#
#(showCache)#::&nbsp;|&nbsp;<a href="CacheResource_p.html?url=#[link]#" target="_blank">Cache</a>#(/showCache)#
#(showProxy)#::&nbsp;|&nbsp;<a href="proxy.html?url=#[link]#" target="_blank">Augmented Browsing</a>#(/showProxy)#
#(showHostBrowser)#::&nbsp;|&nbsp;<a href="HostBrowser.html?path=#[link]#"><img src="env/grafics/minitree.png" width="15" height="8"/></a>#(/showHostBrowser)#
#(showHostBrowser)#::&nbsp;|&nbsp;<a href="HostBrowser.html?path=#[link]#"><img src="env/grafics/minitree.png" width="15" height="8" title="Browse index" alt="Browse index"/></a>#(/showHostBrowser)#
#(showVocabulary)#::<br/>#{vocabulary}##[name]#:#[terms]# #{/vocabulary}##(/showVocabulary)#
#(showSnapshots)#::<a href="#[link]#">Snapshots</a>#(/showSnapshots)#
</p>

@ -26,7 +26,10 @@
import java.awt.Dimension;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
@ -136,17 +139,7 @@ public class yacysearchitem {
prop.put("content_authorized", authenticated ? "1" : "0");
final String urlhash = ASCII.String(result.hash());
if (authenticated) { // only needed if authorized
boolean bookmarkexists;
// check url exists in bookkmarks
bookmarkexists = sb.bookmarksDB.getBookmark(urlhash) != null;
prop.put("content_authorized_bookmark", !bookmarkexists);
// bookmark icon check for YMarks
//prop.put("content_authorized_bookmark", sb.tables.bookmarks.hasBookmark("admin", urlhash) ? "0" : "1");
prop.putHTML("content_authorized_bookmark_bookmarklink", "yacysearch.html?query=" + origQ.replace(' ', '+') + "&Enter=Search&count=" + theSearch.query.itemsPerPage() + "&offset=" + (theSearch.query.neededResults() - theSearch.query.itemsPerPage()) + "&resource=" + resource + "&time=3&bookmarkref=" + urlhash + "&bookmarkurl=" + crypt.simpleEncode(resultUrlstring) + "&urlmaskfilter=.*");
prop.put("content_authorized_recommend", (sb.peers.newsPool.getSpecific(NewsPool.OUTGOING_DB, NewsPool.CATEGORY_SURFTIPP_ADD, "url", resultUrlstring) == null) ? "1" : "0");
prop.putHTML("content_authorized_recommend_deletelink", "yacysearch.html?query=" + origQ.replace(' ', '+') + "&Enter=Search&count=" + theSearch.query.itemsPerPage() + "&offset=" + (theSearch.query.neededResults() - theSearch.query.itemsPerPage()) + "&order=" + crypt.simpleEncode(theSearch.query.ranking.toExternalString()) + "&resource=" + resource + "&time=3&deleteref=" + urlhash + "&urlmaskfilter=.*");
prop.putHTML("content_authorized_recommend_recommendlink", "yacysearch.html?query=" + origQ.replace(' ', '+') + "&Enter=Search&count=" + theSearch.query.itemsPerPage() + "&offset=" + (theSearch.query.neededResults() - theSearch.query.itemsPerPage()) + "&order=" + crypt.simpleEncode(theSearch.query.ranking.toExternalString()) + "&resource=" + resource + "&time=3&recommendref=" + urlhash + "&urlmaskfilter=.*");
prop.put("content_authorized_urlhash", urlhash);
addAuthorizedActions(sb, prop, theSearch, resultUrlstring, resource, origQ, urlhash);
}
prop.putHTML("content_title", result.title());
prop.putXML("content_title-xml", result.title());
@ -399,6 +392,70 @@ public class yacysearchitem {
}
return contentFaviconURL.toString();
}
/**
* Add action links reserved to authorized users. All parameters must be non null.
* @param sb the main Switchboard instance
* @param prop properties map to feed
* @param theSearch search event
* @param resultUrlstring URL of the result item
* @param resource resource scope ("local" or "global")
* @param origQ origin query terms
* @param urlhash URL hash of the result item
*/
private static void addAuthorizedActions(final Switchboard sb, final serverObjects prop,
final SearchEvent theSearch, final String resultUrlstring, final String resource, final String origQ,
final String urlhash) {
// check if url exists in bookmarks
boolean bookmarkexists = sb.bookmarksDB.getBookmark(urlhash) != null;
prop.put("content_authorized_bookmark", !bookmarkexists);
// bookmark icon check for YMarks
//prop.put("content_authorized_bookmark", sb.tables.bookmarks.hasBookmark("admin", urlhash) ? "0" : "1");
/* Bookmark, delete and recommend action links share the same URL prefix */
StringBuilder linkBuilder = new StringBuilder();
String actionLinkPrefix = linkBuilder.append("yacysearch.html?query=").append(origQ.replace(' ', '+'))
.append("&Enter=Search&count=").append(theSearch.query.itemsPerPage()).append("&offset=")
.append((theSearch.query.neededResults() - theSearch.query.itemsPerPage())).append("&resource=")
.append(resource).append("&time=3").toString();
linkBuilder.setLength(0);
String encodedURLString;
try {
encodedURLString = URLEncoder.encode(crypt.simpleEncode(resultUrlstring), StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e1) {
ConcurrentLog.warn("YACY_SEARCH_ITEM", "UTF-8 encoding is not supported!");
encodedURLString = crypt.simpleEncode(resultUrlstring);
}
String bookmarkLink = linkBuilder.append(actionLinkPrefix).append("&bookmarkref=").append(urlhash)
.append("&bookmarkurl=").append(encodedURLString).append("&urlmaskfilter=.*")
.toString();
linkBuilder.setLength(0);
/* Delete and recommend action links share the same URL suffix */
String encodedRanking;
try {
encodedRanking = URLEncoder.encode(crypt.simpleEncode(theSearch.query.ranking.toExternalString()), StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e1) {
ConcurrentLog.warn("YACY_SEARCH_ITEM", "UTF-8 encoding is not supported!");
encodedRanking = crypt.simpleEncode(resultUrlstring);
}
String actionLinkSuffix = linkBuilder.append(urlhash)
.append("&urlmaskfilter=.*").append("&order=").append(encodedRanking).toString();
linkBuilder.setLength(0);
String deleteLink = linkBuilder.append(actionLinkPrefix).append("&deleteref=").append(actionLinkSuffix).toString();
linkBuilder.setLength(0);
String recommendLink = linkBuilder.append(actionLinkPrefix).append("&recommendref=").append(actionLinkSuffix).toString();
linkBuilder.setLength(0);
prop.put("content_authorized_bookmark_bookmarklink", bookmarkLink);
prop.put("content_authorized_recommend_deletelink", deleteLink);
prop.put("content_authorized_recommend_recommendlink", recommendLink);
prop.put("content_authorized_recommend", (sb.peers.newsPool.getSpecific(NewsPool.OUTGOING_DB, NewsPool.CATEGORY_SURFTIPP_ADD, "url", resultUrlstring) == null) ? "1" : "0");
prop.put("content_authorized_urlhash", urlhash);
}
/**

@ -40,12 +40,11 @@
<script>$("#resource-switch-form").popover(); $("[name='resource-switch']").bootstrapSwitch();</script>
#(/resource-select)#
<p class="navbutton">
<p class="navbutton"></p>
<div class="btn-group btn-group-justified">
<div class="btn-group btn-group-xs"><button type="button" id="sort_button_context" class="btn btn-default" onclick="document.getElementById('search').value=document.getElementById('search').value.replace(' /date','');document.searchform.submit();">Context Ranking</button></div>
<div class="btn-group btn-group-xs"><button type="button" id="sort_button_date" class="btn btn-default" onclick="document.getElementById('search').value=document.getElementById('search').value + ' /date';document.searchform.submit();">Sort by Date</button></div>
</div>
</p>
<script>
if (document.getElementById('search').value.indexOf(" /date") == -1) {
document.getElementById("sort_button_context").setAttribute("class","btn btn-default active");
@ -56,7 +55,7 @@
}
</script>
#(searchdomswitches)#::<p class="navbutton">
#(searchdomswitches)#::<p class="navbutton"></p>
<div class="btn-group btn-group-justified">
#(searchtext)#::<div class="btn-group btn-group-xs"><button type="button" class="btn btn-default#(check)#:: active#(/check)#"#(check)# onclick="document.getElementById('contentdom').value='text';document.searchform.submit();"::#(/check)#>Documents</button></div>#(/searchtext)#
#(searchimage)#::<div class="btn-group btn-group-xs"><button type="button" class="btn btn-default#(check)#:: active#(/check)#"#(check)# onclick="document.getElementById('contentdom').value='image';document.searchform.submit();"::#(/check)#>Images</button></div>#(/searchimage)#
@ -64,9 +63,10 @@
#(searchvideo)#::<div class="btn-group btn-group-xs"><button type="button" class="btn btn-default#(check)#:: active#(/check)#"#(check)# onclick="document.getElementById('contentdom').value='video';document.searchform.submit();"::#(/check)#>Video</button></div>#(/searchvideo)#
#(searchapp)#::<div class="btn-group btn-group-xs"><button type="button" class="btn btn-default#(check)#:: active#(/check)#"#(check)# onclick="document.getElementById('contentdom').value='app';document.searchform.submit();"::#(/check)#>Apps</button></div>#(/searchapp)#
</div>
</p>#(/searchdomswitches)#
#(/searchdomswitches)#
#(nav-protocols)#::
<p class="navbutton"></p>
<div class="btn-group btn-group-justified">
#{element}#
<div class="btn-group btn-group-xs"><button type="button" class="btn btn-default#(on)#:: active#(/on)#"#(on)# onclick="window.location.href='#[url]#';"::#(/on)#>#[name]# (#[count]#)</button></div>
@ -76,7 +76,7 @@
#(nav-topics)#<p>&nbsp;</p>::
<div id="tagcloud" style="text-align:justify">#{element}#
<a rel="#[count]#" href="#[url]#" style="text-decoration:none;font-size:#[size]#px;">#[name]#</a>
<a href="#[url]#" style="text-decoration:none;font-size:#[size]#px;">#[name]#</a>
#{/element}#</div>
#(/nav-topics)#

@ -105,12 +105,14 @@ public class yacysearchtrailer {
prop.put("nav-namespace", 1);
navigatorIterator = theSearch.namespaceNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next();
count = theSearch.namespaceNavigator.get(name);
if (count == 0) break;
nav = "inurl%3A" + name;
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "inurl:" + name;
if (!theSearch.query.modifier.toString().contains("inurl:"+name)) {
pos++;
prop.put("nav-namespace_element_" + i + "_on", 1);
@ -120,9 +122,11 @@ public class yacysearchtrailer {
prop.put("nav-namespace_element_" + i + "_on", 0);
prop.put(fileType, "nav-namespace_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-namespace_element_" + i + "_name", name);
prop.put(fileType, "nav-namespace_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-namespace_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-namespace_element_" + i + "_id", "namespace_" + i);
prop.put("nav-namespace_element_" + i + "_count", count);
prop.put("nav-namespace_element_" + i + "_nl", 1);
@ -142,12 +146,14 @@ public class yacysearchtrailer {
prop.put("nav-domains", 1);
navigatorIterator = hostNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next();
count = hostNavigator.get(name);
if (count == 0) break;
nav = "site%3A" + name;
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "site:" + name;
if (theSearch.query.modifier.sitehost == null || !theSearch.query.modifier.sitehost.contains(name)) {
pos++;
prop.put("nav-domains_element_" + i + "_on", 1);
@ -157,9 +163,11 @@ public class yacysearchtrailer {
prop.put("nav-domains_element_" + i + "_on", 0);
prop.put(fileType, "nav-domains_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-domains_element_" + i + "_name", name);
prop.put(fileType, "nav-domains_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-domains_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-domains_element_" + i + "_id", "domains_" + i);
prop.put("nav-domains_element_" + i + "_count", count);
prop.put("nav-domains_element_" + i + "_nl", 1);
@ -180,12 +188,14 @@ public class yacysearchtrailer {
prop.put("nav-languages", 1);
navigatorIterator = languageNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next();
count = languageNavigator.get(name);
if (count == 0) break;
nav = "%2Flanguage%2F" + name;
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "/language/" + name;
if (theSearch.query.modifier.language == null || !theSearch.query.modifier.language.contains(name)) {
pos++;
prop.put("nav-languages_element_" + i + "_on", 1);
@ -195,10 +205,12 @@ public class yacysearchtrailer {
prop.put("nav-languages_element_" + i + "_on", 0);
prop.put(fileType, "nav-languages_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
String longname = ISO639.country(name);
prop.put(fileType, "nav-languages_element_" + i + "_name", longname == null ? name : longname);
prop.put(fileType, "nav-languages_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-languages_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-languages_element_" + i + "_id", "languages_" + i);
prop.put("nav-languages_element_" + i + "_count", count);
prop.put("nav-languages_element_" + i + "_nl", 1);
@ -218,12 +230,14 @@ public class yacysearchtrailer {
prop.put("nav-authors", 1);
navigatorIterator = theSearch.authorNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next().trim();
count = theSearch.authorNavigator.get(name);
if (count == 0) break;
nav = (name.indexOf(' ', 0) < 0) ? "author%3A" + name : "author%3A%28" + name.replace(" ", "+") + "%29";
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = (name.indexOf(' ', 0) < 0) ? "author:" + name : "author:(" + name.replace(" ", "+") + ")";
if (theSearch.query.modifier.author == null || !theSearch.query.modifier.author.contains(name)) {
pos++;
prop.put("nav-authors_element_" + i + "_on", 1);
@ -233,9 +247,11 @@ public class yacysearchtrailer {
prop.put("nav-authors_element_" + i + "_on", 0);
prop.put(fileType, "nav-authors_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-authors_element_" + i + "_name", name);
prop.put(fileType, "nav-authors_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-authors_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-authors_element_" + i + "_id", "authors_" + i);
prop.put("nav-authors_element_" + i + "_count", count);
prop.put("nav-authors_element_" + i + "_nl", 1);
@ -257,12 +273,14 @@ public class yacysearchtrailer {
prop.put("nav-collections", 1);
navigatorIterator = theSearch.collectionNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next().trim();
count = theSearch.collectionNavigator.get(name);
if (count == 0) break;
nav = (name.indexOf(' ', 0) < 0) ? "collection%3A" + name : "collection%3A%28" + name.replace(" ", "+") + "%29";
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = (name.indexOf(' ', 0) < 0) ? "collection:" + name : "collection:(" + name.replace(" ", "+") + ")";
if (theSearch.query.modifier.collection == null || !theSearch.query.modifier.collection.contains(name)) {
pos++;
prop.put("nav-collections_element_" + i + "_on", 1);
@ -272,9 +290,11 @@ public class yacysearchtrailer {
prop.put("nav-collections_element_" + i + "_on", 0);
prop.put(fileType, "nav-collections_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-collections_element_" + i + "_name", name);
prop.put(fileType, "nav-collections_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, true).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-collections_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, true).toString());
prop.put(fileType, "nav-collections_element_" + i + "_id", "collections_" + i);
prop.put("nav-collections_element_" + i + "_count", count);
prop.put("nav-collections_element_" + i + "_nl", 1);
@ -317,7 +337,7 @@ public class yacysearchtrailer {
prop.put("nav-topics_element_" + i + "_on", 1);
prop.put(fileType, "nav-topics_element_" + i + "_modifier", name);
prop.put(fileType, "nav-topics_element_" + i + "_name", name);
prop.put(fileType, "nav-topics_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, name, false).toString());
prop.put("nav-topics_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, name, false).toString());
prop.put("nav-topics_element_" + i + "_count", count);
int fontsize = TOPWORDS_MINSIZE + (TOPWORDS_MAXSIZE - TOPWORDS_MINSIZE) * (count - mincount) / (1 + maxcount - mincount);
fontsize = Math.max(TOPWORDS_MINSIZE, fontsize - (name.length() - 5));
@ -341,7 +361,7 @@ public class yacysearchtrailer {
//theSearch.protocolNavigator.inc("http(s)", httpCount + httpsCount);
navigatorIterator = theSearch.protocolNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
boolean visible = false;
String oldQuery = theSearch.query.getQueryGoal().query_original; // prepare hack to make radio-button like navigation
String oldProtocolModifier = theSearch.query.modifier.protocol;
@ -354,6 +374,8 @@ public class yacysearchtrailer {
if (count == 0) break;
visible = visible || "ftp,smb".indexOf(name) >= 0;
nav = "%2F" + name;
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "/" + name;
if (oldProtocolModifier == null || !oldProtocolModifier.equals(name)) {
pos++;
prop.put("nav-protocols_element_" + i + "_on", 0);
@ -363,10 +385,12 @@ public class yacysearchtrailer {
prop.put("nav-protocols_element_" + i + "_on", 1);
prop.put(fileType, "nav-protocols_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-protocols_element_" + i + "_name", name);
String url = QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString();
prop.put(fileType, "nav-protocols_element_" + i + "_on_url", url);
/* URL is already percent encoded : no need to re-encode specifically for the file type */
String url = QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString();
prop.put("nav-protocols_element_" + i + "_on_url", url);
prop.put("nav-protocols_element_" + i + "_count", count);
prop.put("nav-protocols_element_" + i + "_nl", 1);
i++;
@ -441,12 +465,14 @@ public class yacysearchtrailer {
prop.put("nav-filetypes", 1);
navigatorIterator = theSearch.filetypeNavigator.keys(false);
int i = 0, pos = 0, neg = 0;
String nav;
String nav, rawNav;
while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) {
name = navigatorIterator.next().trim();
count = theSearch.filetypeNavigator.get(name);
if (count == 0) break;
nav = "filetype%3A" + name;
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "filetype:" + name;
if (theSearch.query.modifier.filetype == null || !theSearch.query.modifier.filetype.contains(name) ) {
pos++;
prop.put("nav-filetypes_element_" + i + "_on", 1);
@ -456,9 +482,11 @@ public class yacysearchtrailer {
prop.put("nav-filetypes_element_" + i + "_on", 0);
prop.put(fileType, "nav-filetypes_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-filetypes_element_" + i + "_name", name);
prop.put(fileType, "nav-filetypes_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-filetypes_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-filetypes_element_" + i + "_id", "filetypes_" + i);
prop.put("nav-filetypes_element_" + i + "_count", count);
prop.put("nav-filetypes_element_" + i + "_nl", 1);
@ -483,12 +511,14 @@ public class yacysearchtrailer {
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_navname", navname);
navigatorIterator = ve.getValue().keys(false);
int i = 0;
String nav;
String nav, rawNav;
while (i < 20 && navigatorIterator.hasNext()) {
name = navigatorIterator.next();
count = ve.getValue().get(name);
if (count == 0) break;
nav = "%2Fvocabulary%2F" + navname + "%2F" + MultiProtocolURL.escape(Tagging.encodePrintname(name)).toString();
/* Avoid double percent encoding in QueryParams.navurl */
rawNav = "/vocabulary/" + navname + "/" + MultiProtocolURL.escape(Tagging.encodePrintname(name)).toString();
if (!theSearch.query.modifier.toString().contains("/vocabulary/" + navname + "/" + name.replace(' ', '_'))) {
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_on", 1);
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_modifier", nav);
@ -496,9 +526,11 @@ public class yacysearchtrailer {
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_on", 0);
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_modifier", "-" + nav);
nav="";
rawNav = "";
}
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_name", name);
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, nav, false).toString());
/* URL is already percent encoded : no need to re-encode specifically for the file type */
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString());
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_id", "vocabulary_" + navname + "_" + i);
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_count", count);
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_nl", 1);

Binary file not shown.

Binary file not shown.

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

Loading…
Cancel
Save