Merge branch 'daniel/set-program-id'
diff --git a/app/mapreduce.yaml b/app/mapreduce.yaml
index a03f44b..c0c4994 100644
--- a/app/mapreduce.yaml
+++ b/app/mapreduce.yaml
@@ -46,6 +46,13 @@
     params:
     - name: entity_kind
 
+- name: SetProgramId
+  mapper:
+    input_reader: mapreduce.input_readers.DatastoreKeyInputReader
+    handler: soc.mapreduce.set_program_id.process
+    params:
+    - name: entity_kind
+
 - name: GSoCConvertProjectMentors
   mapper:
     input_reader: mapreduce.input_readers.DatastoreInputReader
diff --git a/app/soc/mapreduce/set_program_id.py b/app/soc/mapreduce/set_program_id.py
new file mode 100644
index 0000000..3a25cd2
--- /dev/null
+++ b/app/soc/mapreduce/set_program_id.py
@@ -0,0 +1,53 @@
+# Copyright 2013 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""MapReduce job that sets program_id property for program entities.
+
+The script works for GSoCProgram and GCIProgram models.
+"""
+
+import logging
+
+from google.appengine.ext import db
+
+from mapreduce import operation
+
+from soc.modules.gci.models.program import GCIProgram
+from soc.modules.gsoc.models.program import GSoCProgram
+
+
+def process(entity_key):
+  """Copies link_id field and writes it to program_id field for the entity with
+  the specified key.
+
+  Args:
+    entity_key: key of the processed entity.
+  """
+  def convert_entity_txn():
+    entity = db.get(entity_key)
+    if not entity:
+      logging.error('Missing entity for key %s.' % entity_key)
+      return False
+
+    # assign program property by its key
+    entity.program_id = entity.link_id
+    db.put(entity)
+    return True
+
+  result = db.run_in_transaction(convert_entity_txn)
+
+  if result:
+    yield operation.counters.Increment('updated_entity')
+  else:
+    yield operation.counters.Increment('missing_entity')
diff --git a/app/soc/models/seed_db.py b/app/soc/models/seed_db.py
index f558deb..254fac5 100644
--- a/app/soc/models/seed_db.py
+++ b/app/soc/models/seed_db.py
@@ -150,6 +150,7 @@
   program_properties = {
       'key_name': 'google/gsoc2009',
       'link_id': 'gsoc2009',
+      'program_id': 'gsoc2009',
       'sponsor': google,
       'scope': google,
       'name': 'Google Summer of Code 2009',
@@ -177,6 +178,7 @@
   program_properties.update({
       'key_name': 'google/gsoc2010',
       'link_id': 'gsoc2010',
+      'program_id': 'gsoc2010',
       'name': 'Google Summer of Code 2010',
       'description': 'This is the program for GSoC 2010.',
       'short_name': 'GSoC 2010',
@@ -207,6 +209,7 @@
   program_properties.update({
       'key_name': 'google/gci2009',
       'link_id': 'gci2009',
+      'program_id': 'gci2009',
       'name': 'Google Code In Contest 2009',
       'short_name': 'GCI 2009',
       'group_label': 'GCI',