diff options
Diffstat (limited to 'src/Wallabag/ImportBundle')
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 | |||
3 | namespace Wallabag\ImportBundle\Command; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
6 | use Symfony\Component\Config\Definition\Exception\Exception; | ||
7 | use Symfony\Component\Console\Input\InputArgument; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Output\OutputInterface; | ||
10 | use Symfony\Component\Console\Helper\ProgressBar; | ||
11 | use Wallabag\CoreBundle\Entity\Entry; | ||
12 | use Wallabag\CoreBundle\Tools\Utils; | ||
13 | |||
14 | class 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 | ||
5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | 5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | 6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
7 | use Symfony\Component\Console\Input\ArrayInput; | ||
8 | use Symfony\Component\Console\Output\NullOutput; | ||
9 | use Symfony\Component\HttpFoundation\Request; | ||
10 | use Wallabag\ImportBundle\Command\ImportCommand; | ||
11 | use Wallabag\ImportBundle\Form\Type\UploadImportType; | ||
7 | 12 | ||
8 | class ImportController extends Controller | 13 | class 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 | |||
3 | namespace Wallabag\ImportBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\FormBuilderInterface; | ||
7 | |||
8 | class 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 %} |