As we know we can perform svn operations like checkout, commit, update using tools like Tortoise svn etc.
Now I am trying to perform svn operations like svn checkout, commit, update using ant script (so svn process will be much easier).
I am trying using svnkit sdk with their given as follows:
/*
* ====================================================================
* Copyright (c) 2004-2010 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
/*
* The following example program demonstrates how you can use SVNRepository to
* obtain a history for a range of revisions including (for each revision): all
* changed paths, log message, the author of the commit, the timestamp when the
* commit was made. It is similar to the "svn log" command supported by the
* Subversion client library.
*
* As an example here's a part of one of the program layouts (for the default
* values):
*
* ---------------------------------------------
* revision: 1240
* author: alex
* date: Tue Aug 02 19:52:49 NOVST 2005
* log message: 0.9.0 is now trunk
*
* changed paths:
* A /trunk (from /branches/0.9.0 revision 1239)
* ---------------------------------------------
* revision: 1263
* author: sa
* date: Wed Aug 03 21:19:55 NOVST 2005
* log message: updated examples, javadoc files
*
* changed paths:
* M /trunk/doc/javadoc-files/javadoc.css
* M /trunk/doc/javadoc-files/overview.html
* M /trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/StatusHandler.java
* ...
*
*/
public class History {
/*
* args parameter is used to obtain a repository location URL, a start
* revision number, an end revision number, user's account name & password
* to authenticate him to the server.
*/
public static void main(String[] args) {
/*
* Default values:
*/
String url = "svnUrl";
String name = "username";
String password = "password";
long startRevision = 0;
long endRevision = -1;//HEAD (the latest) revision
/*
* Initializes the library (it must be done before ever using the
* library itself)
*/
setupLibrary();
if (args != null) {
/*
* Obtains a repository location URL
*/
url = (args.length >= 1) ? args[0] : url;
/*
* Obtains the start point of the revisions range
*/
startRevision = (args.length >= 2) ? Long.parseLong(args[1])
: startRevision;
/*
* Obtains the end point of the revisions range
*/
endRevision = (args.length >= 3) ? Long.parseLong(args[2])
: endRevision;
/*
* Obtains an account name (will be used to authenticate the user to
* the server)
*/
name = (args.length >= 4) ? args[3] : name;
/*
* Obtains a password
*/
password = (args.length >= 5) ? args[4] : password;
}
SVNRepository repository = null;
try {
/*
* Creates an instance of SVNRepository to work with the repository.
* All user's requests to the repository are relative to the
* repository location used to create this SVNRepository.
* SVNURL is a wrapper for URL strings that refer to repository locations.
*/
repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
} catch (SVNException svne) {
/*
* Perhaps a malformed URL is the cause of this exception.
*/
System.err
.println("error while creating an SVNRepository for the location '"
+ url + "': " + svne.getMessage());
System.exit(1);
}
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
repository.setAuthenticationManager(authManager);
/*
* Gets the latest revision number of the repository
*/
try {
endRevision = repository.getLatestRevision();
} catch (SVNException svne) {
System.err.println("error while fetching the latest repository revision: " + svne.getMessage());
System.exit(1);
}
Collection logEntries = null;
try {
logEntries = repository.log(new String[] {""}, null,
startRevision, endRevision, true, true);
} catch (SVNException svne) {
System.out.println("error while collecting log information for '"
+ url + "': " + svne.getMessage());
System.exit(1);
}
for (Iterator entries = logEntries.iterator(); entries.hasNext();) {
/*
* gets a next SVNLogEntry
*/
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
System.out.println("---------------------------------------------");
/*
* gets the revision number
*/
System.out.println("revision: " + logEntry.getRevision());
/*
* gets the author of the changes made in that revision
*/
System.out.println("author: " + logEntry.getAuthor());
/*
* gets the time moment when the changes were committed
*/
System.out.println("date: " + logEntry.getDate());
/*
* gets the commit log message
*/
System.out.println("log message: " + logEntry.getMessage());
/*
* displaying all paths that were changed in that revision; cahnged
* path information is represented by SVNLogEntryPath.
*/
String logMessage = "log message";
try {
ISVNEditor editor = repository.getCommitEditor( logMessage , null /*locks*/ , true /*keepLocks*/ , null /*mediator*/ );
History.copyDir(editor, "C:/svnCommitCode/src","svnurl/src", logEntry.getRevision());
} catch (SVNException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (logEntry.getChangedPaths().size() > 0) {
System.out.println();
System.out.println("changed paths:");
/*
* keys are changed paths
*/
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths
.hasNext();) {
/*
* obtains a next SVNLogEntryPath
*/
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry
.getChangedPaths().get(changedPaths.next());
/*
* SVNLogEntryPath.getPath returns the changed path itself;
*
* SVNLogEntryPath.getType returns a charecter describing
* how the path was changed ('A' - added, 'D' - deleted or
* 'M' - modified);
*
* If the path was copied from another one (branched) then
* SVNLogEntryPath.getCopyPath &
* SVNLogEntryPath.getCopyRevision tells where it was copied
* from and what revision the origin path was at.
*/
System.out.println(" "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : ""));
}
}
}
}
/*
* Initializes the library to work with a repository via
* different protocols.
*/
private static void setupLibrary() {
/*
* For using over http:// and https://
*/
DAVRepositoryFactory.setup();
/*
* For using over svn:// and svn+xxx://
*/
SVNRepositoryFactoryImpl.setup();
/*
* For using over file:///
*/
FSRepositoryFactory.setup();
}
private static SVNCommitInfo copyDir( ISVNEditor editor , String srcDirPath , String dstDirPath , long revision ) throws SVNException {
editor.openRoot( -1 );
editor.addDir( dstDirPath , srcDirPath , revision );
System.out.println("done--------------------");
//Closes dstDirPath.
editor.closeDir( );
//Closes the root directory.
editor.closeDir( );
return editor.closeEdit( );
}
}
I am able to get some of the outputs as history:
revision: 7
author: username
date: Wed Apr 23 15:47:58 2014
log message: testing
changed paths:
A /testCode/src
But I am getting below error when I am calling SVNCommitInfo copyDir() method:
org.tmatesoft.svn.core.SVNException: svn: E160013: '/testCode/!svn/bc/2/C:/svnCommitCode/src' path not found: 404 Not Found (http://svnUrl)
I am providing both source (my local system directory path) and destination path (svn directory path), what I am doing wrong over here? (Means on svn same 'src' folder exist, I just want to replace with current local directory.)
Can anyone guide me in this context?
This solution worked for me.
First call this method getSVNClientManager to get authenticated,it will return clientManager which will be used to get different kind of svn clients instances to do different activities.
public SVNClientManager getSVNClientManager () throws IOException{
SVNURL url = SVNURL
.parseURIDecoded("<path to the base svn repository>");
SVNRepository repository = SVNRepositoryFactory.create(url, null);
ISVNOptions myOptions = SVNWCUtil.createDefaultOptions(true);
//provide svn username and password
//username = name used to connect to svn
//password = password used to connect to svn
ISVNAuthenticationManager myAuthManager = SVNWCUtil
.createDefaultAuthenticationManager("<username>", "<password>");
repository.setAuthenticationManager(myAuthManager);
//clientManager will be used to get different kind of svn clients instances to do different activities
//like update, commit, view diff etc.
SVNClientManager clientManager = SVNClientManager.newInstance(
myOptions, myAuthManager);
return clientManager ;
}
and then call method commitToSvn()
public void commitToSvn(SVNClientManager clientManager)
throws SVNException {
SVNCommitClient commitClient = clientManager.getCommitClient();
File fileToCheckin = new File("LocalDir/SampleFileFolder/SampleFile1");
boolean recursive = true;
SVNCommitInfo importInfo = commitClient
.doImport(
fileToCheckin ,
SVNURL.parseURIDecoded("<path at which we want to check-in the file>"),
"testing svn kit integration", recursive);
System.out.println(importInfo.getNewRevision());
}
Similarly we can call checkout method exportFromSvn()
public void exportFromSvn(SVNClientManager clientManager) throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
SVNURL url = SVNURL.parseURIDecoded("<svn url to export from>");
//destination path
File dstPath = new File("LocalDirNew");
//the revision number which should be looked upon for the file path
SVNRevision pegRevision = SVNRevision.create(<right svn revision number>);
//the revision number which is required to be exported.
SVNRevision revision = SVNRevision.create(<right svn revision number>);
//if there is any special character for end of line (in the file) then it is required. For our use case, //it can be null, assuming there are no special characters. In this case the OS specific EoF style will //be assumed
String eolStyle = null;
//this would force the operation
boolean force = true;
//Till what extent under a directory, export is required, is determined by depth. INFINITY means the whole subtree of that directory will be exported
SVNDepth recursive = SVNDepth.INFINITY;
updateClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive );
}
My desktop application, written in java, tries to download public files from Google Drive. As i found out, it can be implemented by using file's webContentLink (it's for ability to download public files without user authorization).
So, the code below works with small files:
String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();
But it doesn't work on big files, because in this case file can't be downloaded directly via webContentLink without user confirmation with google virus scan warning. See an example: web content link.
So my question is how to get content of a public file from Google Drive without user authorization?
Update December 8th, 2015
According to Google Support using the
googledrive.com/host/ID
method will be turned off on Aug 31st, 2016.
I just ran into this issue.
The trick is to treat your Google Drive folder like a web host.
Update April 1st, 2015
Google Drive has changed and there's a simple way to direct link to your drive. I left my previous answers below for reference but to here's an updated answer.
Create a Public folder in Google Drive.
Share this drive publicly.
Get your Folder UUID from the address bar when you're in that folder
Put that UUID in this URL
https://googledrive.com/host/<folder UUID>/
Add the file name to where your file is located.
https://googledrive.com/host/<folder UUID>/<file name>
Which is intended functionality by Google
new Google Drive Link.
All you have to do is simple get the host URL for a publicly shared drive folder. To do this, you can upload a plain HTML file and preview it in Google Drive to find your host URL.
Here are the steps:
Create a folder in Google Drive.
Share this drive publicly.
Upload a simple HTML file. Add any additional files (subfolders ok)
Open and "preview" the HTML file in Google Drive
Get the URL address for this folder
Create a direct link URL from your URL folder base
This URL should allow direct downloads of your large files.
[edit]
I forgot to add. If you use subfolders to organize your files, you simple use the folder name as you would expect in a URL hierarchy.
https://googledrive.com/host/<your public folders id string>/images/my-image.png
What I was looking to do
I created a custom Debian image with Virtual Box for Vagrant. I wanted to share this ".box" file with colleagues so they could put the direct link into their Vagrantfile.
In the end, I needed a direct link to the actual file.
Google Drive problem
If you set the file permissions to be publicly available and create/generate a direct access link by using something like the gdocs2direct tool or just crafting the link yourself:
https://docs.google.com/uc?export=download&id=<your file id>
You will get a cookie based verification code and prompt "Google could not scan this file" prompt, which won't work for things such as wget or Vagrantfile configs.
The code that it generates is a simple code that appends GET query variable ...&confirm=### to the string, but it's per user specific, so it's not like you can copy/paste that query variable for others.
But if you use the above "Web page hosting" method, you can get around that prompt.
I hope that helps!
If you face the "This file cannot be checked for viruses" intermezzo page, the download is not that easy.
You essentially need to first download the normal download link, which however redirects you to the "Download anyway" page. You need to store cookies from this first request, find out the link pointed to by the "Download anyway" button, and then use this link to download the file, but reusing the cookies you got from the first request.
Here's a bash variant of the download process using CURL:
curl -c /tmp/cookies "https://drive.google.com/uc?export=download&id=DOCUMENT_ID" > /tmp/intermezzo.html
curl -L -b /tmp/cookies "https://drive.google.com$(cat /tmp/intermezzo.html | grep -Po 'uc-download-link" [^>]* href="\K[^"]*' | sed 's/\&/\&/g')" > FINAL_DOWNLOADED_FILENAME
Notes:
this procedure will probably stop working after some Google changes
the grep command uses Perl syntax (-P) and the \K "operator" which essentially means "do not include anything preceding \K to the matched result. I don't know which version of grep introduced these options, but ancient or non-Ubuntu versions probably don't have it
a Java solution would be more or less the same, just take a HTTPS library which can handle cookies, and some nice text-parsing library
I know this is an old question but I could not find a solution to this problem after some research, so I am sharing what worked for me.
I have written this C# code for one of my projects. It can bypass the scan virus warning programmatically. The code can probably be converted to Java.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Text;
public class FileDownloader : IDisposable
{
private const string GOOGLE_DRIVE_DOMAIN = "drive.google.com";
private const string GOOGLE_DRIVE_DOMAIN2 = "https://drive.google.com";
// In the worst case, it is necessary to send 3 download requests to the Drive address
// 1. an NID cookie is returned instead of a download_warning cookie
// 2. download_warning cookie returned
// 3. the actual file is downloaded
private const int GOOGLE_DRIVE_MAX_DOWNLOAD_ATTEMPT = 3;
public delegate void DownloadProgressChangedEventHandler( object sender, DownloadProgress progress );
// Custom download progress reporting (needed for Google Drive)
public class DownloadProgress
{
public long BytesReceived, TotalBytesToReceive;
public object UserState;
public int ProgressPercentage
{
get
{
if( TotalBytesToReceive > 0L )
return (int) ( ( (double) BytesReceived / TotalBytesToReceive ) * 100 );
return 0;
}
}
}
// Web client that preserves cookies (needed for Google Drive)
private class CookieAwareWebClient : WebClient
{
private class CookieContainer
{
private readonly Dictionary<string, string> cookies = new Dictionary<string, string>();
public string this[Uri address]
{
get
{
string cookie;
if( cookies.TryGetValue( address.Host, out cookie ) )
return cookie;
return null;
}
set
{
cookies[address.Host] = value;
}
}
}
private readonly CookieContainer cookies = new CookieContainer();
public DownloadProgress ContentRangeTarget;
protected override WebRequest GetWebRequest( Uri address )
{
WebRequest request = base.GetWebRequest( address );
if( request is HttpWebRequest )
{
string cookie = cookies[address];
if( cookie != null )
( (HttpWebRequest) request ).Headers.Set( "cookie", cookie );
if( ContentRangeTarget != null )
( (HttpWebRequest) request ).AddRange( 0 );
}
return request;
}
protected override WebResponse GetWebResponse( WebRequest request, IAsyncResult result )
{
return ProcessResponse( base.GetWebResponse( request, result ) );
}
protected override WebResponse GetWebResponse( WebRequest request )
{
return ProcessResponse( base.GetWebResponse( request ) );
}
private WebResponse ProcessResponse( WebResponse response )
{
string[] cookies = response.Headers.GetValues( "Set-Cookie" );
if( cookies != null && cookies.Length > 0 )
{
int length = 0;
for( int i = 0; i < cookies.Length; i++ )
length += cookies[i].Length;
StringBuilder cookie = new StringBuilder( length );
for( int i = 0; i < cookies.Length; i++ )
cookie.Append( cookies[i] );
this.cookies[response.ResponseUri] = cookie.ToString();
}
if( ContentRangeTarget != null )
{
string[] rangeLengthHeader = response.Headers.GetValues( "Content-Range" );
if( rangeLengthHeader != null && rangeLengthHeader.Length > 0 )
{
int splitIndex = rangeLengthHeader[0].LastIndexOf( '/' );
if( splitIndex >= 0 && splitIndex < rangeLengthHeader[0].Length - 1 )
{
long length;
if( long.TryParse( rangeLengthHeader[0].Substring( splitIndex + 1 ), out length ) )
ContentRangeTarget.TotalBytesToReceive = length;
}
}
}
return response;
}
}
private readonly CookieAwareWebClient webClient;
private readonly DownloadProgress downloadProgress;
private Uri downloadAddress;
private string downloadPath;
private bool asyncDownload;
private object userToken;
private bool downloadingDriveFile;
private int driveDownloadAttempt;
public event DownloadProgressChangedEventHandler DownloadProgressChanged;
public event AsyncCompletedEventHandler DownloadFileCompleted;
public FileDownloader()
{
webClient = new CookieAwareWebClient();
webClient.DownloadProgressChanged += DownloadProgressChangedCallback;
webClient.DownloadFileCompleted += DownloadFileCompletedCallback;
downloadProgress = new DownloadProgress();
}
public void DownloadFile( string address, string fileName )
{
DownloadFile( address, fileName, false, null );
}
public void DownloadFileAsync( string address, string fileName, object userToken = null )
{
DownloadFile( address, fileName, true, userToken );
}
private void DownloadFile( string address, string fileName, bool asyncDownload, object userToken )
{
downloadingDriveFile = address.StartsWith( GOOGLE_DRIVE_DOMAIN ) || address.StartsWith( GOOGLE_DRIVE_DOMAIN2 );
if( downloadingDriveFile )
{
address = GetGoogleDriveDownloadAddress( address );
driveDownloadAttempt = 1;
webClient.ContentRangeTarget = downloadProgress;
}
else
webClient.ContentRangeTarget = null;
downloadAddress = new Uri( address );
downloadPath = fileName;
downloadProgress.TotalBytesToReceive = -1L;
downloadProgress.UserState = userToken;
this.asyncDownload = asyncDownload;
this.userToken = userToken;
DownloadFileInternal();
}
private void DownloadFileInternal()
{
if( !asyncDownload )
{
webClient.DownloadFile( downloadAddress, downloadPath );
// This callback isn't triggered for synchronous downloads, manually trigger it
DownloadFileCompletedCallback( webClient, new AsyncCompletedEventArgs( null, false, null ) );
}
else if( userToken == null )
webClient.DownloadFileAsync( downloadAddress, downloadPath );
else
webClient.DownloadFileAsync( downloadAddress, downloadPath, userToken );
}
private void DownloadProgressChangedCallback( object sender, DownloadProgressChangedEventArgs e )
{
if( DownloadProgressChanged != null )
{
downloadProgress.BytesReceived = e.BytesReceived;
if( e.TotalBytesToReceive > 0L )
downloadProgress.TotalBytesToReceive = e.TotalBytesToReceive;
DownloadProgressChanged( this, downloadProgress );
}
}
private void DownloadFileCompletedCallback( object sender, AsyncCompletedEventArgs e )
{
if( !downloadingDriveFile )
{
if( DownloadFileCompleted != null )
DownloadFileCompleted( this, e );
}
else
{
if( driveDownloadAttempt < GOOGLE_DRIVE_MAX_DOWNLOAD_ATTEMPT && !ProcessDriveDownload() )
{
// Try downloading the Drive file again
driveDownloadAttempt++;
DownloadFileInternal();
}
else if( DownloadFileCompleted != null )
DownloadFileCompleted( this, e );
}
}
// Downloading large files from Google Drive prompts a warning screen and requires manual confirmation
// Consider that case and try to confirm the download automatically if warning prompt occurs
// Returns true, if no more download requests are necessary
private bool ProcessDriveDownload()
{
FileInfo downloadedFile = new FileInfo( downloadPath );
if( downloadedFile == null )
return true;
// Confirmation page is around 50KB, shouldn't be larger than 60KB
if( downloadedFile.Length > 60000L )
return true;
// Downloaded file might be the confirmation page, check it
string content;
using( var reader = downloadedFile.OpenText() )
{
// Confirmation page starts with <!DOCTYPE html>, which can be preceeded by a newline
char[] header = new char[20];
int readCount = reader.ReadBlock( header, 0, 20 );
if( readCount < 20 || !( new string( header ).Contains( "<!DOCTYPE html>" ) ) )
return true;
content = reader.ReadToEnd();
}
int linkIndex = content.LastIndexOf( "href=\"/uc?" );
if( linkIndex < 0 )
return true;
linkIndex += 6;
int linkEnd = content.IndexOf( '"', linkIndex );
if( linkEnd < 0 )
return true;
downloadAddress = new Uri( "https://drive.google.com" + content.Substring( linkIndex, linkEnd - linkIndex ).Replace( "&", "&" ) );
return false;
}
// Handles the following formats (links can be preceeded by https://):
// - drive.google.com/open?id=FILEID
// - drive.google.com/file/d/FILEID/view?usp=sharing
// - drive.google.com/uc?id=FILEID&export=download
private string GetGoogleDriveDownloadAddress( string address )
{
int index = address.IndexOf( "id=" );
int closingIndex;
if( index > 0 )
{
index += 3;
closingIndex = address.IndexOf( '&', index );
if( closingIndex < 0 )
closingIndex = address.Length;
}
else
{
index = address.IndexOf( "file/d/" );
if( index < 0 ) // address is not in any of the supported forms
return string.Empty;
index += 7;
closingIndex = address.IndexOf( '/', index );
if( closingIndex < 0 )
{
closingIndex = address.IndexOf( '?', index );
if( closingIndex < 0 )
closingIndex = address.Length;
}
}
return string.Concat( "https://drive.google.com/uc?id=", address.Substring( index, closingIndex - index ), "&export=download" );
}
public void Dispose()
{
webClient.Dispose();
}
}
And here's how you can use it:
// NOTE: FileDownloader is IDisposable!
FileDownloader fileDownloader = new FileDownloader();
// This callback is triggered for DownloadFileAsync only
fileDownloader.DownloadProgressChanged += ( sender, e ) => Console.WriteLine( "Progress changed " + e.BytesReceived + " " + e.TotalBytesToReceive );
// This callback is triggered for both DownloadFile and DownloadFileAsync
fileDownloader.DownloadFileCompleted += ( sender, e ) => Console.WriteLine( "Download completed" );
fileDownloader.DownloadFileAsync( "https://INSERT_DOWNLOAD_LINK_HERE", #"C:\downloadedFile.txt" );
#Case 1: download file with small size.
You can use url with format https://drive.google.com/uc?export=download&id=FILE_ID and then inputstream of file can be obtained directly.
#Case 2: download file with large size.
You stuck a wall of a virus scan alert page returned. By parsing html dom element, I tried to get link with confirm code under button "Download anyway" but it didn't work. Its may required cookie or session info.
enter image description here
SOLUTION:
Finally I found solution for two above cases. Just need to put httpConnection.setDoOutput(true) in connection step to get a Json.
)]}' { "disposition":"SCAN_CLEAN",
"downloadUrl":"http:www...",
"fileName":"exam_list_json.txt", "scanResult":"OK", "sizeBytes":2392}
Then, you can use any Json parser to read downloadUrl, fileName and sizeBytes.
You can refer follow snippet, hope it help.
private InputStream gConnect(String remoteFile) throws IOException{
URL url = new URL(remoteFile);
URLConnection connection = url.openConnection();
if(connection instanceof HttpURLConnection){
HttpURLConnection httpConnection = (HttpURLConnection) connection;
connection.setAllowUserInteraction(false);
httpConnection.setInstanceFollowRedirects(true);
httpConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows 2000)");
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("GET");
httpConnection.connect();
int reqCode = httpConnection.getResponseCode();
if(reqCode == HttpURLConnection.HTTP_OK){
InputStream is = httpConnection.getInputStream();
Map<String, List<String>> map = httpConnection.getHeaderFields();
List<String> values = map.get("content-type");
if(values != null && !values.isEmpty()){
String type = values.get(0);
if(type.contains("text/html")){
String cookie = httpConnection.getHeaderField("Set-Cookie");
String temp = Constants.getPath(mContext, Constants.PATH_TEMP) + "/temp.html";
if(saveGHtmlFile(is, temp)){
String href = getRealUrl(temp);
if(href != null){
return parseUrl(href, cookie);
}
}
} else if(type.contains("application/json")){
String temp = Constants.getPath(mContext, Constants.PATH_TEMP) + "/temp.txt";
if(saveGJsonFile(is, temp)){
FileDataSet data = JsonReaderHelper.readFileDataset(new File(temp));
if(data.getPath() != null){
return parseUrl(data.getPath());
}
}
}
}
return is;
}
}
return null;
}
And
public static FileDataSet readFileDataset(File file) throws IOException{
FileInputStream is = new FileInputStream(file);
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginObject();
FileDataSet rs = new FileDataSet();
while(reader.hasNext()){
String name = reader.nextName();
if(name.equals("downloadUrl")){
rs.setPath(reader.nextString());
} else if(name.equals("fileName")){
rs.setName(reader.nextString());
} else if(name.equals("sizeBytes")){
rs.setSize(reader.nextLong());
} else {
reader.skipValue();
}
}
reader.endObject();
return rs;
}
This seems to be updated again as of May 19, 2015:
How I got it to work:
As in jmbertucci's recently updated answer, make your folder public to everyone. This is a bit more complicated than before, you have to click Advanced to change the folder to "On - Public on the web."
Find your folder UUID as before--just go into the folder and find your UUID in the address bar:
https://drive.google.com/drive/folders/<folder UUID>
Then head to
https://googledrive.com/host/<folder UUID>
It will redirect you to an index type page with a giant subdomain, but you should be able to see the files in your folder. Then you can right click to save the link to the file you want (I noticed that this direct link also has this big subdomain for googledrive.com). Worked great for me with wget.
This also seems to work with others' shared folders.
e.g.,
https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing
maps to
https://googledrive.com/host/0B7l10Bj_LprhQnpSRkpGMGV2eE0
And a right click can save a direct link to any of those files.
Using a Service Account might work for you.
Check this out:
wget https://raw.githubusercontent.com/circulosmeos/gdown.pl/master/gdown.pl
chmod +x gdown.pl
./gdown.pl https://drive.google.com/file/d/FILE_ID/view TARGET_PATH
Update as of August 2020:
This is what worked for me recently -
Upload your file and get a shareable link which anyone can see(Change permission from "Restricted" to "Anyone with the Link" in the share link options)
Then run:
SHAREABLE_LINK=<google drive shareable link>
curl -L https://drive.google.com/uc\?id\=$(echo $SHAREABLE_LINK | cut -f6 -d"/")
If you just want to programmatically (as oppossed to giving the user a link to open in a browser) download a file through the Google Drive API, I would suggest using the downloadUrl of the file instead of the webContentLink, as documented here: https://developers.google.com/drive/web/manage-downloads
https://github.com/google/skicka
I used this command line tool to download files from Google Drive. Just follow the instructions in Getting Started section and you should download files from Google Drive in minutes.
For any shared link replace FILENAME and FILEID, (for very large files requiring confirmation):
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=FILEID' -O- | sed -rn 's/.confirm=([0-9A-Za-z_]+)./\1\n/p')&id=FILEID" -O FILENAME && rm -rf /tmp/cookies.txt
(For small files):
wget --no-check-certificate 'https://docs.google.com/uc?export=download&id=FILEID' -O FILENAME
I would consider downloading from the link, scraping the page that you get to grab the confirmation link, and then downloading that.
If you look at the "download anyway" URL it has an extra confirm query parameter with a seemingly randomly generated token. Since it's random...and you probably don't want to figure out how to generate it yourself, scraping might be the easiest way without knowing anything about how the site works.
You may need to consider various scenarios.
I simply create a javascript so that it automatically capture the link and download and close the tab with the help of tampermonkey.
// ==UserScript==
// #name Bypass Google drive virus scan
// #namespace SmartManoj
// #version 0.1
// #description Quickly get the download link
// #author SmartManoj
// #match https://drive.google.com/uc?id=*&export=download*
// #grant none
// ==/UserScript==
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
await sleep(5000);
window.close();
}
(function() {
location.replace(document.getElementById("uc-download-link").href);
demo();
})();
Similarly you can get the html source of the url and download in java.
I faced an issue in direct download because I was logged in using multiple Google accounts.
Solution is append authUser=0 parameter. Sample request URL to download :https://drive.google.com/uc?id=FILEID&authuser=0&export=download
https://drive.google.com/uc?export=download&id=FILE_ID replace the FILE_ID with file id.
if you don't know were is file id then check this article Article LINK
I'm trying to link classes from the JDK into the scaladoc-generated doc.
I've used the -doc-external-doc option of scaladoc 2.10.1 but without success.
I'm using -doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api/, but I get links such as index.html#java.io.File instead of index.html?java/io/File.html.
Seems like this option only works for scaladoc-generated doc.
Did I miss an option in scaladoc or should I fill a feature request?
I've configured sbt as follows:
scalacOptions in (Compile,doc) += "-doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api"
Note: I've seen the Opts.doc.externalAPI util in the upcoming sbt 0.13. I think a nice addition (not sure if it's possible) would be to pass a ModuleID instead of a File. The util would figure out which file corresponds to the ModuleID.
I use sbt 0.13.5.
There's no out-of-the-box way to have the feature of having Javadoc links inside scaladoc. And as my understanding goes, it's not sbt's fault, but the way scaladoc works. As Josh pointed out in his comment You should report to scaladoc.
There's however a workaround I came up with - postprocess the doc-generated scaladoc so the Java URLs get replaced to form proper Javadoc links.
The file scaladoc.sbt should be placed inside a sbt project and whenever doc task gets executed, the postprocessing via fixJavaLinksTask task kicks in.
NOTE There are lots of hardcoded paths so use it with caution (aka do the polishing however you see fit).
import scala.util.matching.Regex.Match
autoAPIMappings := true
// builds -doc-external-doc
apiMappings += (
file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") ->
url("http://docs.oracle.com/javase/8/docs/api")
)
lazy val fixJavaLinksTask = taskKey[Unit](
"Fix Java links - replace #java.io.File with ?java/io/File.html"
)
fixJavaLinksTask := {
println("Fixing Java links")
val t = (target in (Compile, doc)).value
(t ** "*.html").get.filter(hasJavadocApiLink).foreach { f =>
println("fixing " + f)
val newContent = javadocApiLink.replaceAllIn(IO.read(f), fixJavaLinks)
IO.write(f, newContent)
}
}
val fixJavaLinks: Match => String = m =>
m.group(1) + "?" + m.group(2).replace(".", "/") + ".html"
val javadocApiLink = """\"(http://docs\.oracle\.com/javase/8/docs/api/index\.html)#([^"]*)\"""".r
def hasJavadocApiLink(f: File): Boolean = (javadocApiLink findFirstIn IO.read(f)).nonEmpty
fixJavaLinksTask <<= fixJavaLinksTask triggeredBy (doc in Compile)
I took the answer by #jacek-laskowski and modified it so that it avoid hard-coded strings and could be used for any number of Java libraries, not just the standard one.
Edit: the location of rt.jar is now determined from the runtime using sun.boot.class.path and does not have to be hard coded.
The only thing you need to modify is the map, which I have called externalJavadocMap in the following:
import scala.util.matching.Regex
import scala.util.matching.Regex.Match
val externalJavadocMap = Map(
"owlapi" -> "http://owlcs.github.io/owlapi/apidocs_4_0_2/index.html"
)
/*
* The rt.jar file is located in the path stored in the sun.boot.class.path system property.
* See the Oracle documentation at http://docs.oracle.com/javase/6/docs/technotes/tools/findingclasses.html.
*/
val rtJar: String = System.getProperty("sun.boot.class.path").split(java.io.File.pathSeparator).collectFirst {
case str: String if str.endsWith(java.io.File.separator + "rt.jar") => str
}.get // fail hard if not found
val javaApiUrl: String = "http://docs.oracle.com/javase/8/docs/api/index.html"
val allExternalJavadocLinks: Seq[String] = javaApiUrl +: externalJavadocMap.values.toSeq
def javadocLinkRegex(javadocURL: String): Regex = ("""\"(\Q""" + javadocURL + """\E)#([^"]*)\"""").r
def hasJavadocLink(f: File): Boolean = allExternalJavadocLinks exists {
javadocURL: String =>
(javadocLinkRegex(javadocURL) findFirstIn IO.read(f)).nonEmpty
}
val fixJavaLinks: Match => String = m =>
m.group(1) + "?" + m.group(2).replace(".", "/") + ".html"
/* You can print the classpath with `show compile:fullClasspath` in the SBT REPL.
* From that list you can find the name of the jar for the managed dependency.
*/
lazy val documentationSettings = Seq(
apiMappings ++= {
// Lookup the path to jar from the classpath
val classpath = (fullClasspath in Compile).value
def findJar(nameBeginsWith: String): File = {
classpath.find { attributed: Attributed[File] => (attributed.data ** s"$nameBeginsWith*.jar").get.nonEmpty }.get.data // fail hard if not found
}
// Define external documentation paths
(externalJavadocMap map {
case (name, javadocURL) => findJar(name) -> url(javadocURL)
}) + (file(rtJar) -> url(javaApiUrl))
},
// Override the task to fix the links to JavaDoc
doc in Compile <<= (doc in Compile) map {
target: File =>
(target ** "*.html").get.filter(hasJavadocLink).foreach { f =>
//println(s"Fixing $f.")
val newContent: String = allExternalJavadocLinks.foldLeft(IO.read(f)) {
case (oldContent: String, javadocURL: String) =>
javadocLinkRegex(javadocURL).replaceAllIn(oldContent, fixJavaLinks)
}
IO.write(f, newContent)
}
target
}
)
I am using SBT 0.13.8.
Whenever a user enters "~" as an argument, my program replaces it with System.getProperty("user.home").
After debugging, I see that this replaces "~" with "C:UsersSoulBeaver" and not "C:/Users/SoulBeaver".
Going through previous questions about incorrect user.home folders, I found out that Java tries to fetch the path from
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
However, I'm using Windows 8 and there is seemingly nothing wrong:
At this point I'm assuming Java "eats" the backslash... so how do I prevent that from happening?
Update
Since the code was requested, here it is. This is taken from Allen Holub's Solving Java's Configuration Problem
/**
* For every enum element in the array, treat keys[i].name() as a key
* and load the associated value from the following places (in order):
*
* <ol>
* <li>a -D command-line switch (in System properties)</li>
* <li>if no -D value found, an environment variable with the same name as the key</li>
* <li>if no environment found, the default stored in the Enum element itself</li>
* </ol>
*
* That value must identify an existing directory in the file system, and a
* File representing that location can be retrieved from {#link #directory(Enum)}.
*
* #param keys The values() array associated with the enum that's using this class.
* #throws IllegalStateException if a given key doesn't have a value associated with it
* or if that value doesn't identify an existing directory.
*/
public LocationsSupport(T[] keys) throws IllegalStateException {
StringBuilder logMessage = new StringBuilder("Loaded environment/-D properties:\n");
try {
for (T element : keys) {
String how = "???";
String key = element.name();
String value;
if ((value = System.getProperty(key)) != null)
how = "from system property (-D)";
else if ((value = System.getenv(key)) != null)
how = "from environment";
else if ((value = element.defaultValue()) != null)
how = "from default. Mapped from: " + value;
if (value != null)
value = value.replaceAll("~", System.getProperty("user.home"));
if (value == null || value.isEmpty())
throw new IllegalStateException("Value for " +key +" cannot be null or empty.");
File location = new File(value);
createLocationIfNecessary(location, element.createIfNecessary());
if (!location.isDirectory())
throw new IllegalStateException("Location specified in "
+key
+" (" +asString(location) +") "
+"does not exist or is not a directory.");
dictionary.put(key, location);
logMessage.append("\t");
logMessage.append(key);
logMessage.append("=");
logMessage.append(asString(location) );
logMessage.append(" (");
logMessage.append(how);
logMessage.append(")\n");
}
} finally {
if (log.getAllAppenders() instanceof NullEnumeration)
System.err.println(logMessage);
else
log.info(logMessage);
}
}
It's failing at trying to locate the default location for CONFIG:
public enum Places implements Locations {
CONFIG ("~/config"),
HOME ("~"),
TMP ("~/tmp", true),
TERM_STORE ("~/tmp/indices/term_store/", true),
RESOURCE_STORE ("~/tmp/indices/resource_store/", true),
PERSON_STORE ("~/tmp/indices/person_store/", true);
I am using Java 1.7.0_13 and IntelliJ IDEA 12.1.3
You are using regular expression based replacement. In the replacement pattern for java regexes, the '\' character is special. you need to pass the user home dir through Matcher.quoteReplacement() before using it as a replacement pattern (as covered in the javadoc for the relevant method).
may be following can give some info.
Bug
Discussion