Merge pull request #1026 from atom/set-data-path

Add API to set/get path to special directory or file
This commit is contained in:
Cheng Zhao 2015-01-18 21:53:29 -08:00
commit e75950cb89
8 changed files with 117 additions and 35 deletions

View file

@ -16,6 +16,7 @@
#include "base/environment.h" #include "base/environment.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
#include "native_mate/callback.h" #include "native_mate/callback.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
@ -26,10 +27,6 @@
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#if defined(OS_LINUX)
#include "base/nix/xdg_util.h"
#endif
using atom::Browser; using atom::Browser;
namespace mate { namespace mate {
@ -64,6 +61,30 @@ namespace api {
namespace { namespace {
// Return the path constant from string.
int GetPathConstant(const std::string& name) {
if (name == "appData")
return brightray::DIR_APP_DATA;
else if (name == "userData")
return brightray::DIR_USER_DATA;
else if (name == "cache")
return brightray::DIR_CACHE;
else if (name == "userCache")
return brightray::DIR_USER_CACHE;
else if (name == "home")
return base::DIR_HOME;
else if (name == "temp")
return base::DIR_TEMP;
else if (name == "userDesktop")
return base::DIR_USER_DESKTOP;
else if (name == "exe")
return base::FILE_EXE;
else if (name == "module")
return base::FILE_MODULE;
else
return -1;
}
class ResolveProxyHelper { class ResolveProxyHelper {
public: public:
ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback) ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
@ -142,19 +163,26 @@ void App::OnFinishLaunching() {
Emit("ready"); Emit("ready");
} }
base::FilePath App::GetDataPath() { base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
bool succeed = false;
base::FilePath path; base::FilePath path;
#if defined(OS_LINUX) int key = GetPathConstant(name);
scoped_ptr<base::Environment> env(base::Environment::Create()); if (key >= 0)
path = base::nix::GetXDGDirectory(env.get(), succeed = PathService::Get(key, &path);
base::nix::kXdgConfigHomeEnvVar, if (!succeed)
base::nix::kDotConfigDir); args->ThrowError("Failed to get path");
#else return path;
PathService::Get(base::DIR_APP_DATA, &path); }
#endif
return path.Append(base::FilePath::FromUTF8Unsafe( void App::SetPath(mate::Arguments* args,
Browser::Get()->GetName())); const std::string& name,
const base::FilePath& path) {
bool succeed = false;
int key = GetPathConstant(name);
if (key >= 0)
succeed = PathService::Override(key, path);
if (!succeed)
args->ThrowError("Failed to set path");
} }
void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
@ -187,7 +215,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
.SetMethod("setUserTasks", .SetMethod("setUserTasks",
base::Bind(&Browser::SetUserTasks, browser)) base::Bind(&Browser::SetUserTasks, browser))
#endif #endif
.SetMethod("getDataPath", &App::GetDataPath) .SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath)
.SetMethod("resolveProxy", &App::ResolveProxy) .SetMethod("resolveProxy", &App::ResolveProxy)
.SetMethod("setDesktopName", &App::SetDesktopName); .SetMethod("setDesktopName", &App::SetDesktopName);
} }

View file

@ -18,6 +18,10 @@ namespace base {
class FilePath; class FilePath;
} }
namespace mate {
class Arguments;
}
namespace atom { namespace atom {
namespace api { namespace api {
@ -48,7 +52,12 @@ class App : public mate::EventEmitter,
v8::Isolate* isolate) override; v8::Isolate* isolate) override;
private: private:
base::FilePath GetDataPath(); // Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
void SetPath(mate::Arguments* args,
const std::string& name,
const base::FilePath& path);
void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void SetDesktopName(const std::string& desktop_name); void SetDesktopName(const std::string& desktop_name);

View file

@ -5,9 +5,6 @@ bindings = process.atomBinding 'app'
app = bindings.app app = bindings.app
app.__proto__ = EventEmitter.prototype app.__proto__ = EventEmitter.prototype
app.getHomeDir = ->
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
app.setApplicationMenu = (menu) -> app.setApplicationMenu = (menu) ->
require('menu').setApplicationMenu menu require('menu').setApplicationMenu menu
@ -32,6 +29,9 @@ if process.platform is 'darwin'
app.once 'ready', -> app.emit 'finish-launching' app.once 'ready', -> app.emit 'finish-launching'
app.terminate = app.quit app.terminate = app.quit
app.exit = process.exit app.exit = process.exit
app.getHomeDir = -> app.getPath 'home'
app.getDataPath = -> app.getPath 'userData'
app.setDataPath = (path) -> app.setPath 'userData', path
# Only one App object pemitted. # Only one App object pemitted.
module.exports = app module.exports = app

View file

@ -41,6 +41,8 @@ if (option.file && !option.webdriver) {
app.setName(packageJson.productName); app.setName(packageJson.productName);
else if (packageJson.name) else if (packageJson.name)
app.setName(packageJson.name); app.setName(packageJson.name);
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
} }
// Run the app. // Run the app.

View file

@ -34,15 +34,9 @@ getExtensionInfoFromPath = (srcDirectory) ->
srcDirectory: srcDirectory srcDirectory: srcDirectory
extensionInfoMap[manifest.name] extensionInfoMap[manifest.name]
# Load persistented extensions. # The loaded extensions cache and its persistent path.
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions' loadedExtensions = null
loadedExtensionsPath = null
try
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
loadedExtensions = [] unless Array.isArray loadedExtensions
# Preheat the extensionInfo cache.
getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions
catch e
# Persistent loaded extensions. # Persistent loaded extensions.
app.on 'will-quit', -> app.on 'will-quit', ->
@ -59,6 +53,16 @@ app.once 'ready', ->
protocol = require 'protocol' protocol = require 'protocol'
BrowserWindow = require 'browser-window' BrowserWindow = require 'browser-window'
# Load persistented extensions.
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
try
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
loadedExtensions = [] unless Array.isArray loadedExtensions
# Preheat the extensionInfo cache.
getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions
catch e
# The chrome-extension: can map a extension URL request to real file path. # The chrome-extension: can map a extension URL request to real file path.
protocol.registerProtocol 'chrome-extension', (request) -> protocol.registerProtocol 'chrome-extension', (request) ->
parsed = url.parse request.url parsed = url.parse request.url

View file

@ -90,6 +90,10 @@ process.once 'BIND_DONE', ->
else else
app.setDesktopName '#{app.getName()}.desktop' app.setDesktopName '#{app.getName()}.desktop'
# Set the user path according to application's name.
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
# Load the chrome extension support. # Load the chrome extension support.
require './chrome-extension.js' require './chrome-extension.js'

View file

@ -91,13 +91,47 @@ executed. It is possible that a window cancels the quitting by returning
Quit the application directly, it will not try to close all windows so cleanup Quit the application directly, it will not try to close all windows so cleanup
code will not run. code will not run.
## app.getDataPath() ## app.getPath(name)
Returns the path for storing configuration files, with app name appended. * `name` String
* `%APPDATA%\MyAppName` on Windows Retrieves a path to a special directory or file associated with `name`. On
* `~/.config/MyAppName` on Linux failure an `Error` would throw.
* `~/Library/Application Support/MyAppName` on OS X
You can request following paths by the names:
* `home`: User's home directory
* `appData`: Per-user application data directory, by default it is pointed to:
* `%APPDATA%` on Windows
* `$XDG_CONFIG_HOME` or `~/.config` on Linux
* `~/Library/Application Support` on OS X
* `userData`: The directory for storing your app's configuration files, by
default it is the `appData` directory appended with your app's name
* `cache`: Per-user application cache directory, by default it is pointed to:
* `%APPDATA%` on Window, which doesn't has a universal place for cache
* `$XDG_CACHE_HOME` or `~/.cache` on Linux
* `~/Library/Caches` on OS X
* `userCache`: The directory for placing your app's caches, by default it is the
`cache` directory appended with your app's name
* `temp`: Temporary directory
* `userDesktop`: The current user's Desktop directory
* `exe`: The current executable file
* `module`: The `libchromiumcontent` library
## app.setPath(name, path)
* `name` String
* `path` String
Overrides the `path` to a special directory or file associated with `name`. if
the path specifies a directory that does not exist, the directory will be
created by this method. On failure an `Error` would throw.
You can only override paths of `name`s defined in `app.getPath`.
By default web pages' cookies and caches will be stored under `userData`
directory, if you want to change this location, you have to override the
`userData` path before the `ready` event of `app` module gets emitted.
## app.getVersion() ## app.getVersion()

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit 09dc5f11e9c83e6ff3c2b6b1b58ceb2b8eae35c4 Subproject commit ad17292154ddd2436c377bbe2d10fa213338f4fa