aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/ImportBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/ImportBundle')
-rw-r--r--src/Wallabag/ImportBundle/Command/ImportCommand.php124
-rw-r--r--src/Wallabag/ImportBundle/Controller/ImportController.php48
-rw-r--r--src/Wallabag/ImportBundle/DependencyInjection/Configuration.php8
-rw-r--r--src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php1
-rw-r--r--src/Wallabag/ImportBundle/Form/Type/UploadImportType.php29
-rw-r--r--src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig26
6 files changed, 234 insertions, 2 deletions
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php
new file mode 100644
index 00000000..3fb8927d
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php
@@ -0,0 +1,124 @@
1<?php
2
3namespace Wallabag\ImportBundle\Command;
4
5use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6use Symfony\Component\Config\Definition\Exception\Exception;
7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Helper\ProgressBar;
11use Wallabag\CoreBundle\Entity\Entry;
12use Wallabag\CoreBundle\Tools\Utils;
13
14class ImportCommand extends ContainerAwareCommand
15{
16 protected function configure()
17 {
18 $this
19 ->setName('wallabag:import')
20 ->setDescription('Import entries from JSON file')
21 ->addArgument(
22 'userId',
23 InputArgument::REQUIRED,
24 'user ID to populate'
25 );
26 }
27
28 protected function execute(InputInterface $input, OutputInterface $output)
29 {
30 $now = new \DateTime();
31 $output->writeln('<comment>Start : '.$now->format('d-m-Y G:i:s').' ---</comment>');
32
33 // Importing CSV on DB via Doctrine ORM
34 $this->import($input, $output);
35
36 $now = new \DateTime();
37 $output->writeln('<comment>End : '.$now->format('d-m-Y G:i:s').' ---</comment>');
38 }
39
40 protected function import(InputInterface $input, OutputInterface $output)
41 {
42 // Getting php array of data from CSV
43 $data = $this->get($input, $output);
44
45 $em = $this->getContainer()->get('doctrine')->getManager();
46 // Turning off doctrine default logs queries for saving memory
47 $em->getConnection()->getConfiguration()->setSQLLogger(null);
48
49 // Define the size of record, the frequency for persisting the data and the current index of records
50 $size = count($data);
51 $batchSize = 20;
52 $i = 1;
53
54 $user = $em->getRepository('WallabagUserBundle:User')
55 ->findOneById($input->getArgument('userId'));
56
57 if (!is_object($user)) {
58 throw new Exception('User not found');
59 }
60
61 $progress = new ProgressBar($output, $size);
62 $progress->start();
63
64 foreach ($data as $object) {
65 $array = (array) $object;
66 $entry = $em->getRepository('WallabagCoreBundle:Entry')
67 ->findOneByUrl($array['url']);
68
69 if (!is_object($entry)) {
70 $entry = new Entry($user);
71 $entry->setUrl($array['url']);
72 }
73
74 $entry->setTitle($array['title']);
75 $entry->setArchived($array['is_read']);
76 $entry->setStarred($array['is_fav']);
77 $entry->setContent($array['content']);
78 $entry->setReadingTime(Utils::getReadingTime($array['content']));
79
80 $em->persist($entry);
81
82 if (($i % $batchSize) === 0) {
83 $em->flush();
84 $progress->advance($batchSize);
85
86 $now = new \DateTime();
87 $output->writeln(' of entries imported ... | '.$now->format('d-m-Y G:i:s'));
88 }
89 ++$i;
90 }
91
92 $em->flush();
93 $em->clear();
94 $progress->finish();
95 }
96
97 protected function convert($filename)
98 {
99 if (!file_exists($filename) || !is_readable($filename)) {
100 return false;
101 }
102
103 $header = null;
104 $data = array();
105
106 if (($handle = fopen($filename, 'r')) !== false) {
107 while (($row = fgets($handle)) !== false) {
108 $data = json_decode($row);
109 }
110 fclose($handle);
111 }
112
113 return $data;
114 }
115
116 protected function get(InputInterface $input, OutputInterface $output)
117 {
118 $filename = __DIR__.'/../../../../web/uploads/import/'.$input->getArgument('userId').'.json';
119
120 $data = $this->convert($filename);
121
122 return $data;
123 }
124}
diff --git a/src/Wallabag/ImportBundle/Controller/ImportController.php b/src/Wallabag/ImportBundle/Controller/ImportController.php
index 3569793b..6ebd6a0a 100644
--- a/src/Wallabag/ImportBundle/Controller/ImportController.php
+++ b/src/Wallabag/ImportBundle/Controller/ImportController.php
@@ -4,14 +4,58 @@ namespace Wallabag\ImportBundle\Controller;
4 4
5use Symfony\Bundle\FrameworkBundle\Controller\Controller; 5use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 6use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
7use Symfony\Component\Console\Input\ArrayInput;
8use Symfony\Component\Console\Output\NullOutput;
9use Symfony\Component\HttpFoundation\Request;
10use Wallabag\ImportBundle\Command\ImportCommand;
11use Wallabag\ImportBundle\Form\Type\UploadImportType;
7 12
8class ImportController extends Controller 13class ImportController extends Controller
9{ 14{
10 /** 15 /**
11 * @Route("/import", name="import") 16 * @Route("/import", name="import")
12 */ 17 */
13 public function importAction() 18 public function importAction(Request $request)
14 { 19 {
15 return $this->render('WallabagImportBundle:Import:index.html.twig', array()); 20 $importForm = $this->createForm(new UploadImportType());
21 $importForm->handleRequest($request);
22 $user = $this->getUser();
23
24 if ($importForm->isValid()) {
25 $file = $importForm->get('file')->getData();
26 $name = $user->getId().'.json';
27 $dir = __DIR__.'/../../../../web/uploads/import';
28
29 if (in_array($file->getMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($dir, $name)) {
30 $command = new ImportCommand();
31 $command->setContainer($this->container);
32 $input = new ArrayInput(array('userId' => $user->getId()));
33 $return = $command->run($input, new NullOutput());
34
35 if ($return == 0) {
36 $this->get('session')->getFlashBag()->add(
37 'notice',
38 'Import successful'
39 );
40 } else {
41 $this->get('session')->getFlashBag()->add(
42 'notice',
43 'Import failed'
44 );
45 }
46
47 return $this->redirect('/');
48 } else {
49 $this->get('session')->getFlashBag()->add(
50 'notice',
51 'Error while processing import. Please verify your import file.'
52 );
53 }
54 }
55
56 return $this->render('WallabagImportBundle:Import:index.html.twig', array(
57 'form' => array(
58 'import' => $importForm->createView(), ),
59 ));
16 } 60 }
17} 61}
diff --git a/src/Wallabag/ImportBundle/DependencyInjection/Configuration.php b/src/Wallabag/ImportBundle/DependencyInjection/Configuration.php
index bacaff31..2ef35463 100644
--- a/src/Wallabag/ImportBundle/DependencyInjection/Configuration.php
+++ b/src/Wallabag/ImportBundle/DependencyInjection/Configuration.php
@@ -12,6 +12,14 @@ class Configuration implements ConfigurationInterface
12 $treeBuilder = new TreeBuilder(); 12 $treeBuilder = new TreeBuilder();
13 $rootNode = $treeBuilder->root('wallabag_import'); 13 $rootNode = $treeBuilder->root('wallabag_import');
14 14
15 $rootNode
16 ->children()
17 ->arrayNode('allow_mimetypes')
18 ->prototype('scalar')->end()
19 ->end()
20 ->end()
21 ;
22
15 return $treeBuilder; 23 return $treeBuilder;
16 } 24 }
17} 25}
diff --git a/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php b/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php
index 4efcaace..38163886 100644
--- a/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php
+++ b/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php
@@ -13,6 +13,7 @@ class WallabagImportExtension extends Extension
13 { 13 {
14 $configuration = new Configuration(); 14 $configuration = new Configuration();
15 $config = $this->processConfiguration($configuration, $configs); 15 $config = $this->processConfiguration($configuration, $configs);
16 $container->setParameter('wallabag_import.allow_mimetypes', $config['allow_mimetypes']);
16 17
17 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 18 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
18 $loader->load('services.yml'); 19 $loader->load('services.yml');
diff --git a/src/Wallabag/ImportBundle/Form/Type/UploadImportType.php b/src/Wallabag/ImportBundle/Form/Type/UploadImportType.php
new file mode 100644
index 00000000..5d894318
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Form/Type/UploadImportType.php
@@ -0,0 +1,29 @@
1<?php
2
3namespace Wallabag\ImportBundle\Form\Type;
4
5use Symfony\Component\Form\AbstractType;
6use Symfony\Component\Form\FormBuilderInterface;
7
8class UploadImportType extends AbstractType
9{
10 public function buildForm(FormBuilderInterface $builder, array $options)
11 {
12 $builder
13 ->add('file', 'file')
14 ->add('save', 'submit')
15 ;
16 }
17
18 public function getDefaultOptions(array $options)
19 {
20 return array(
21 'csrf_protection' => false,
22 );
23 }
24
25 public function getName()
26 {
27 return 'upload_import_file';
28 }
29}
diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
index fda21f2d..ee759a52 100644
--- a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
+++ b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
@@ -13,4 +13,30 @@
13 </div> 13 </div>
14 </div> 14 </div>
15</div> 15</div>
16
17
18<div class="row">
19 <div class="col s12">
20 <div class="card-panel settings">
21 <div class="row">
22 <div class="col s12">
23 <form action="{{ path('import') }}" method="post" {{ form_enctype(form.import) }}>
24 {{ form_errors(form.import) }}
25 <div class="row">
26 <div class="input-field col s12">
27 <p>{% trans %}Please select your wallabag export and click on the below button to upload and import it.{% endtrans %}</p>
28 {{ form_errors(form.import.file) }}
29 {{ form_widget(form.import.file) }}
30 </div>
31 </div>
32 <div class="hidden">{{ form_rest(form.import) }}</div>
33 <button class="btn waves-effect waves-light" type="submit" name="action">
34 {% trans %}Upload file{% endtrans %}
35 </button>
36 </form>
37 </div>
38 </div>
39 </div>
40 </div>
41</div>
16{% endblock %} 42{% endblock %}