summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/base/mixins.scss16
-rw-r--r--app/assets/stylesheets/pages/notes.scss16
-rw-r--r--app/controllers/import/google_code_controller.rb111
-rw-r--r--app/models/project.rb9
-rw-r--r--app/views/import/google_code/new.html.haml60
-rw-r--r--app/views/import/google_code/new_user_map.html.haml20
-rw-r--r--app/views/import/google_code/status.html.haml49
-rw-r--r--app/views/projects/new.html.haml4
-rw-r--r--app/workers/repository_import_worker.rb2
9 files changed, 273 insertions, 14 deletions
diff --git a/app/assets/stylesheets/base/mixins.scss b/app/assets/stylesheets/base/mixins.scss
index ccba65e3fd5..216f25cdcd5 100644
--- a/app/assets/stylesheets/base/mixins.scss
+++ b/app/assets/stylesheets/base/mixins.scss
@@ -119,6 +119,22 @@
li {
line-height: 1.5;
}
+
+ a[href*="/uploads/"], a[href*="storage.googleapis.com/google-code-attachments/"] {
+ &:before {
+ margin-right: 4px;
+
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ content: "\f0c6";
+ }
+
+ &:hover:before {
+ text-decoration: none;
+ }
+ }
}
@mixin str-truncated($max_width: 82%) {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index d66093bc2e5..facd7e19314 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -62,20 +62,8 @@ ul.notes {
word-wrap: break-word;
@include md-typography;
- a[href*="/uploads/"] {
- &:before {
- margin-right: 4px;
-
- font: normal normal normal 14px/1 FontAwesome;
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- content: "\f0c6";
- }
-
- &:hover:before {
- text-decoration: none;
- }
+ hr {
+ margin: 10px 0;
}
}
}
diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb
new file mode 100644
index 00000000000..fb4ef987367
--- /dev/null
+++ b/app/controllers/import/google_code_controller.rb
@@ -0,0 +1,111 @@
+class Import::GoogleCodeController < Import::BaseController
+ before_filter :user_map, only: [:new_user_map, :create_user_map]
+
+ def new
+
+ end
+
+ def callback
+ dump_file = params[:dump_file]
+
+ unless dump_file.respond_to?(:read)
+ return redirect_to :back, alert: "You need to upload a Google Takeout archive."
+ end
+
+ begin
+ dump = JSON.parse(dump_file.read)
+ rescue
+ return redirect_to :back, alert: "The uploaded file is not a valid Google Takeout archive."
+ end
+
+ client = Gitlab::GoogleCodeImport::Client.new(dump)
+ unless client.valid?
+ return redirect_to :back, alert: "The uploaded file is not a valid Google Takeout archive."
+ end
+
+ session[:google_code_dump] = dump
+
+ if params[:create_user_map] == "1"
+ redirect_to new_user_map_import_google_code_path
+ else
+ redirect_to status_import_google_code_path
+ end
+ end
+
+ def new_user_map
+
+ end
+
+ def create_user_map
+ user_map_json = params[:user_map]
+ user_map_json = "{}" if user_map_json.blank?
+
+ begin
+ user_map = JSON.parse(user_map_json)
+ rescue
+ flash.now[:alert] = "The entered user map is not a valid JSON user map."
+
+ render "new_user_map" and return
+ end
+
+ unless user_map.is_a?(Hash) && user_map.all? { |k, v| k.is_a?(String) && v.is_a?(String) }
+ flash.now[:alert] = "The entered user map is not a valid JSON user map."
+
+ render "new_user_map" and return
+ end
+
+ session[:google_code_user_map] = user_map
+
+ flash[:notice] = "The user map has been saved. Continue by selecting the projects you want to import."
+
+ redirect_to status_import_google_code_path
+ end
+
+ def status
+ unless client.valid?
+ return redirect_to new_import_google_path
+ end
+
+ @repos = client.repos
+
+ @already_added_projects = current_user.created_projects.where(import_type: "google_code")
+ already_added_projects_names = @already_added_projects.pluck(:import_source)
+
+ @repos.reject! { |repo| already_added_projects_names.include? repo.name }
+ end
+
+ def jobs
+ jobs = current_user.created_projects.where(import_type: "google_code").to_json(only: [:id, :import_status])
+ render json: jobs
+ end
+
+ def create
+ @repo_id = params[:repo_id]
+ repo = client.repo(@repo_id)
+ @target_namespace = current_user.namespace
+ @project_name = repo.name
+
+ namespace = @target_namespace
+
+ user_map = session[:google_code_user_map]
+
+ @project = Gitlab::GoogleCodeImport::ProjectCreator.new(repo, namespace, current_user, user_map).execute
+ end
+
+ private
+
+ def client
+ @client ||= Gitlab::GoogleCodeImport::Client.new(session[:google_code_dump])
+ end
+
+ def user_map
+ @user_map ||= begin
+ user_map = client.user_map
+
+ stored_user_map = session[:google_code_user_map]
+ user_map.update(stored_user_map) if stored_user_map
+
+ Hash[user_map.sort]
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index dcbafd76475..c4f50e02ddd 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -27,6 +27,7 @@
# import_type :string(255)
# import_source :string(255)
# avatar :string(255)
+# import_data :text
#
require 'carrierwave/orm/activerecord'
@@ -50,6 +51,8 @@ class Project < ActiveRecord::Base
default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets
+ serialize :import_data, JSON
+
# set last_activity_at to the same as created_at
after_create :set_last_activity_at
def set_last_activity_at
@@ -185,6 +188,7 @@ class Project < ActiveRecord::Base
state :failed
after_transition any => :started, do: :add_import_job
+ after_transition any => :finished, do: :clear_import_data
end
class << self
@@ -262,6 +266,11 @@ class Project < ActiveRecord::Base
RepositoryImportWorker.perform_in(2.seconds, id)
end
+ def clear_import_data
+ self.import_data = nil
+ self.save
+ end
+
def import?
import_url.present?
end
diff --git a/app/views/import/google_code/new.html.haml b/app/views/import/google_code/new.html.haml
new file mode 100644
index 00000000000..ce78fec205f
--- /dev/null
+++ b/app/views/import/google_code/new.html.haml
@@ -0,0 +1,60 @@
+%h3.page-title
+ %i.fa.fa-google
+ Import projects from Google Code
+%hr
+
+= form_tag callback_import_google_code_path, class: 'form-horizontal', multipart: true do
+ %p
+ Follow the steps below to export your Google Code project data.
+ In the next step, you'll be able to select the projects you want to import.
+ %ol
+ %li
+ %p
+ Go to
+ #{link_to "Google Takeout", "https://www.google.com/settings/takeout", target: "_blank"}.
+ %li
+ %p
+ Make sure you're logged into the account that owns the projects you'd like to import.
+ %li
+ %p
+ Click the <strong>Select none</strong> button on the right, since we only need "Google Code Project Hosting".
+ %li
+ %p
+ Scroll down to <strong>Google Code Project Hosting</strong> and enable the switch on the right.
+ %li
+ %p
+ Choose <strong>Next</strong> at the bottom of the page.
+ %li
+ %p
+ Leave the "File type" and "Delivery method" options on their default values.
+ %li
+ %p
+ Choose <strong>Create archive</strong> and wait for archiving to complete.
+ %li
+ %p
+ Click the <strong>Download</strong> button and wait for downloading to complete.
+ %li
+ %p
+ Find the downloaded ZIP file and decompress it.
+ %li
+ %p
+ Find the newly extracted <code>Takeout/Google Code Project Hosting/GoogleCodeProjectHosting.json</code> file.
+ %li
+ %p
+ Upload <code>GoogleCodeProjectHosting.json</code> here:
+ %p
+ %input{type: "file", name: "dump_file", id: "dump_file"}
+ %li
+ %p
+ Do you want to customize how Google Code email addresses and usernames are imported into GitLab?
+ %p
+ = label_tag :create_user_map_0 do
+ = radio_button_tag :create_user_map, 0, true
+ No, directly import the existing email addresses and usernames.
+ %p
+ = label_tag :create_user_map_1 do
+ = radio_button_tag :create_user_map, 1, false
+ Yes, let me map Google Code users to full names or GitLab users.
+ %li
+ %p
+ = submit_tag 'Continue to the next step', class: "btn btn-create"
diff --git a/app/views/import/google_code/new_user_map.html.haml b/app/views/import/google_code/new_user_map.html.haml
new file mode 100644
index 00000000000..d55fcfc97a8
--- /dev/null
+++ b/app/views/import/google_code/new_user_map.html.haml
@@ -0,0 +1,20 @@
+%h3.page-title
+ %i.fa.fa-google
+ Import projects from Google Code
+%hr
+
+= form_tag create_user_map_import_google_code_path, class: 'form-horizontal' do
+ %p
+ Customize how Google Code email addresses and usernames are imported into GitLab.
+ In the next step, you'll be able to select the projects you want to import.
+ %p
+ The user map is a JSON document mapping Google Code users (as keys) to the way they will be imported into GitLab (as values). By default the username is masked to ensure users' privacy.
+ %p
+ To map a Google Code user to a full name or GitLab user, simply replace the value, e.g. <code>"johnsmith@gmail.com": "John Smith"</code> or <code>"johnsmith@gmail.com": "@johnsmith"</code>. Be sure to preserve the surrounding double quotes and other punctuation.
+
+ .form-group
+ .col-sm-12
+ = text_area_tag :user_map, JSON.pretty_generate(@user_map), class: 'form-control', rows: 15
+
+ .form-actions
+ = submit_tag 'Continue to the next step', class: "btn btn-create"
diff --git a/app/views/import/google_code/status.html.haml b/app/views/import/google_code/status.html.haml
new file mode 100644
index 00000000000..2013b8c03c6
--- /dev/null
+++ b/app/views/import/google_code/status.html.haml
@@ -0,0 +1,49 @@
+%h3.page-title
+ %i.fa.fa-google
+ Import projects from Google Code
+
+%p.light
+ Select projects you want to import.
+%p.light
+ Optionally, you can
+ = link_to "customize", new_user_map_import_google_code_path
+ how Google Code email addresses and usernames are imported into GitLab.
+%hr
+%p
+ = button_tag 'Import all projects', class: "btn btn-success js-import-all"
+
+%table.table.import-jobs
+ %thead
+ %tr
+ %th From Google Code
+ %th To GitLab
+ %th Status
+ %tbody
+ - @already_added_projects.each do |project|
+ %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
+ %td
+ = link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank"
+ %td
+ %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
+ %td.job-status
+ - if project.import_status == 'finished'
+ %span
+ %i.fa.fa-check
+ done
+ - elsif project.import_status == 'started'
+ %i.fa.fa-spinner.fa-spin
+ started
+ - else
+ = project.human_import_status_name
+
+ - @repos.each do |repo|
+ %tr{id: "repo_#{repo.id}"}
+ %td
+ = link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank"
+ %td.import-target
+ = "#{current_user.username}/#{repo.name}"
+ %td.import-actions.job-status
+ = button_tag "Import", class: "btn js-add-to-import"
+
+:coffeescript
+ new ImporterStatus("#{jobs_import_google_code_path}", "#{import_google_code_path}")
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 69909a8554e..a06c85b4251 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -62,6 +62,10 @@
%i.icon-gitorious.icon-gitorious-small
Gitorious.org
+ = link_to new_import_google_code_path, class: 'btn' do
+ %i.fa.fa-google
+ Google Code
+
= link_to "#", class: 'btn js-toggle-button' do
%i.fa.fa-git
%span Any repo by URL
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 437640d2305..e6a50afedb1 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -18,6 +18,8 @@ class RepositoryImportWorker
Gitlab::GitlabImport::Importer.new(project).execute
elsif project.import_type == 'bitbucket'
Gitlab::BitbucketImport::Importer.new(project).execute
+ elsif project.import_type == 'google_code'
+ Gitlab::GoogleCodeImport::Importer.new(project).execute
else
true
end